From 148b50b1a4a80255cf3d3ce5d9c370ba2d39df2d Mon Sep 17 00:00:00 2001 From: Ken Dreyer Date: Fri, 13 Nov 2015 11:00:56 -0700 Subject: [PATCH 1/8] ansible: use stricter permissions on public cert Prevent the public SSL certificate from being world-writable. --- deploy/playbooks/roles/common/tasks/nginx.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/deploy/playbooks/roles/common/tasks/nginx.yml b/deploy/playbooks/roles/common/tasks/nginx.yml index ef9f9071..08f17f7e 100644 --- a/deploy/playbooks/roles/common/tasks/nginx.yml +++ b/deploy/playbooks/roles/common/tasks/nginx.yml @@ -55,7 +55,9 @@ - name: make sure permissions are correct for crt file: path: /etc/ssl/certs/{{ ansible_fqdn }}-bundled.crt - mode: 0777 + owner: root + group: root + mode: 0644 when: development_server sudo: true From f5ab261df63138f4b1249446bb488180de19a93b Mon Sep 17 00:00:00 2001 From: Ken Dreyer Date: Fri, 13 Nov 2015 11:04:15 -0700 Subject: [PATCH 2/8] ansible: set key permissions Prior to this change, we weren't enforcing the .key file permissions with Ansible (we did it by hand). Use Ansible to make sure we're doing this right. --- deploy/playbooks/roles/common/tasks/nginx.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/deploy/playbooks/roles/common/tasks/nginx.yml b/deploy/playbooks/roles/common/tasks/nginx.yml index 08f17f7e..100e56f1 100644 --- a/deploy/playbooks/roles/common/tasks/nginx.yml +++ b/deploy/playbooks/roles/common/tasks/nginx.yml @@ -61,6 +61,14 @@ when: development_server sudo: true +- name: make sure permissions are correct for key + file: + path: /etc/ssl/private/{{ ansible_fqdn }}.key + owner: root + group: root + mode: 0600 + sudo: true + - name: ensure nginx is restarted sudo: true action: service name=nginx state=restarted From 62b85dedadf723446bbe6f7f4032e20ff1d3312a Mon Sep 17 00:00:00 2001 From: Ken Dreyer Date: Fri, 13 Nov 2015 11:11:42 -0700 Subject: [PATCH 3/8] ansible: reformat file module to multiple lines style change only; no functional change. --- deploy/playbooks/roles/common/tasks/main.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/deploy/playbooks/roles/common/tasks/main.yml b/deploy/playbooks/roles/common/tasks/main.yml index 586d3662..25f0a574 100644 --- a/deploy/playbooks/roles/common/tasks/main.yml +++ b/deploy/playbooks/roles/common/tasks/main.yml @@ -2,7 +2,12 @@ - name: "ensure a home for {{ app_name }}" sudo: yes - file: path={{ app_home }} owner={{ ansible_ssh_user }} group={{ ansible_ssh_user }} state=directory recurse=yes + file: + path: "{{ app_home }}" + owner: "{{ ansible_ssh_user }}" + group: "{{ ansible_ssh_user }}" + state: directory + recurse: yes register: app_home_created - name: Update apt cache From 2848246e49389c6857af8376ad3b5e4e03122b79 Mon Sep 17 00:00:00 2001 From: Ken Dreyer Date: Fri, 13 Nov 2015 11:14:52 -0700 Subject: [PATCH 4/8] ansible: explain file paths creation Ansible sets up some particular paths need to be writable by the UID that runs the chacra app. Make this more explicit in the Ansible name. --- deploy/playbooks/roles/common/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/playbooks/roles/common/tasks/main.yml b/deploy/playbooks/roles/common/tasks/main.yml index 25f0a574..77827cf1 100644 --- a/deploy/playbooks/roles/common/tasks/main.yml +++ b/deploy/playbooks/roles/common/tasks/main.yml @@ -54,7 +54,7 @@ virtualenv: "{{ app_home }}" notify: restart app -- name: ensure file paths are set properly +- name: ensure writable file paths are set properly sudo: true file: path: "{{ item }}" From abbad6594927d35c023daa4eda9b5e6777f6a000 Mon Sep 17 00:00:00 2001 From: Ken Dreyer Date: Fri, 13 Nov 2015 11:21:58 -0700 Subject: [PATCH 5/8] ansible: secure /etc/circus permissions Restrict /etc/circus and /etc/circus/circus.ini write permissions to root only. --- deploy/playbooks/roles/common/tasks/circus.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/deploy/playbooks/roles/common/tasks/circus.yml b/deploy/playbooks/roles/common/tasks/circus.yml index 8bacd548..9aa68967 100644 --- a/deploy/playbooks/roles/common/tasks/circus.yml +++ b/deploy/playbooks/roles/common/tasks/circus.yml @@ -11,7 +11,9 @@ file: path: /etc/circus state: directory - owner: "{{ ansible_ssh_user }}" + owner: root + group: root + mode: 0755 recurse: yes sudo: true @@ -30,6 +32,9 @@ template: src: circus.conf dest: /etc/init/circus.conf + owner: root + group: root + mode: 0644 sudo: true register: circus_service From 08922b7c68ef97a6db40b976903b5a6f12d26e95 Mon Sep 17 00:00:00 2001 From: Ken Dreyer Date: Fri, 13 Nov 2015 12:28:30 -0700 Subject: [PATCH 6/8] ansible: secure app_home permissions The only thing that needs to write into this location is Ansible, and that can be done with sudo/root permissions. --- deploy/playbooks/roles/common/tasks/main.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/deploy/playbooks/roles/common/tasks/main.yml b/deploy/playbooks/roles/common/tasks/main.yml index 77827cf1..471c6399 100644 --- a/deploy/playbooks/roles/common/tasks/main.yml +++ b/deploy/playbooks/roles/common/tasks/main.yml @@ -4,8 +4,9 @@ sudo: yes file: path: "{{ app_home }}" - owner: "{{ ansible_ssh_user }}" - group: "{{ ansible_ssh_user }}" + owner: root + group: root + mode: 0755 state: directory recurse: yes register: app_home_created From 5c529ad25f32acc8ae544130d15950b251a87aee Mon Sep 17 00:00:00 2001 From: Ken Dreyer Date: Fri, 13 Nov 2015 16:07:02 -0700 Subject: [PATCH 7/8] ansible: install nginx package in nginx.yml This makes nignx.yml more self-contained, so we can move it around. (A future commit will move it to the top of main.yml.) This is code-reorganization only, no functional change. --- deploy/playbooks/roles/common/tasks/nginx.yml | 9 +++++++++ deploy/playbooks/roles/common/vars/main.yml | 1 - 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/deploy/playbooks/roles/common/tasks/nginx.yml b/deploy/playbooks/roles/common/tasks/nginx.yml index 100e56f1..0d98157b 100644 --- a/deploy/playbooks/roles/common/tasks/nginx.yml +++ b/deploy/playbooks/roles/common/tasks/nginx.yml @@ -1,4 +1,13 @@ --- + +- name: install nginx package + sudo: true + apt: + name: nginx + state: present + tags: + - packages + - name: ensure sites-available for nginx file: path=/etc/nginx/sites-available state=directory sudo: true diff --git a/deploy/playbooks/roles/common/vars/main.yml b/deploy/playbooks/roles/common/vars/main.yml index c6406d95..e4251c8c 100644 --- a/deploy/playbooks/roles/common/vars/main.yml +++ b/deploy/playbooks/roles/common/vars/main.yml @@ -11,7 +11,6 @@ system_packages: - postgresql-common - postgresql-contrib - python-psycopg2 - - nginx - vim # needed for the ansible apt_repository module - python-apt From e8a2a907a8900218befd5c198e160b4222156ee4 Mon Sep 17 00:00:00 2001 From: Ken Dreyer Date: Fri, 13 Nov 2015 16:08:42 -0700 Subject: [PATCH 8/8] ansible: run application as "nginx" UID Prior to this commit, the chacra application would run as the "admin" UID ( {{ ansible_ssh_user }} ). This account has sudo privileges and it will be safer to run the application under a UID that cannot sudo. I've selected the "nginx" UID because it is one that we create explicitly, so it's guaranteed to be present on both CentOS and Ubuntu. --- deploy/playbooks/deploy.yml | 1 + deploy/playbooks/deploy_vagrant.yml | 1 + .../playbooks/roles/common/tasks/circus.yml | 14 ++++++-- deploy/playbooks/roles/common/tasks/main.yml | 35 ++++++++++++------- .../roles/common/tasks/postgresql.yml | 9 +++++ .../roles/common/templates/circus.conf | 2 +- 6 files changed, 47 insertions(+), 15 deletions(-) diff --git a/deploy/playbooks/deploy.yml b/deploy/playbooks/deploy.yml index a39179c1..1b22c7c4 100644 --- a/deploy/playbooks/deploy.yml +++ b/deploy/playbooks/deploy.yml @@ -16,3 +16,4 @@ repos_root: "/opt/repos" branch: "master" development_server: false + app_user: "nginx" diff --git a/deploy/playbooks/deploy_vagrant.yml b/deploy/playbooks/deploy_vagrant.yml index 0fa5d60a..afd74aa4 100644 --- a/deploy/playbooks/deploy_vagrant.yml +++ b/deploy/playbooks/deploy_vagrant.yml @@ -17,3 +17,4 @@ repos_root: "/opt/repos" branch: "master" development_server: true + app_user: "nginx" diff --git a/deploy/playbooks/roles/common/tasks/circus.yml b/deploy/playbooks/roles/common/tasks/circus.yml index 9aa68967..a240c2d0 100644 --- a/deploy/playbooks/roles/common/tasks/circus.yml +++ b/deploy/playbooks/roles/common/tasks/circus.yml @@ -1,6 +1,7 @@ --- - name: install circus in virtualenv + sudo: true pip: name={{ item }} state=present virtualenv={{ app_home }} with_items: - circus @@ -21,12 +22,21 @@ file: path: /var/log/circus state: directory - owner: "{{ ansible_ssh_user }}" + owner: "{{ app_user }}" + group: root + mode: 0755 recurse: yes sudo: true - name: ensure {{ app_home }}/log exists - file: path="{{ app_home }}/log" state=directory + sudo: true + file: + path: "{{ app_home }}/log" + state: directory + owner: "{{ app_user }}" + group: root + mode: 0755 + recurse: yes - name: install circus.conf init file template: diff --git a/deploy/playbooks/roles/common/tasks/main.yml b/deploy/playbooks/roles/common/tasks/main.yml index 471c6399..79807baa 100644 --- a/deploy/playbooks/roles/common/tasks/main.yml +++ b/deploy/playbooks/roles/common/tasks/main.yml @@ -1,5 +1,14 @@ --- +- name: Update apt cache + apt: + update_cache: yes + sudo: yes + +- include: nginx.yml + tags: + - nginx + - name: "ensure a home for {{ app_name }}" sudo: yes file: @@ -11,11 +20,6 @@ recurse: yes register: app_home_created -- name: Update apt cache - apt: - update_cache: yes - sudo: yes - - name: install ssl system requirements sudo: yes apt: name={{ item }} state=present @@ -32,23 +36,33 @@ - packages - name: Create a virtualenv with latest pip. + sudo: true pip: name=pip virtualenv={{ app_home }} extra_args='--upgrade' - name: "pip+git install {{ app_name }} into virtualenv." + sudo: true pip: name='git+https://github.com/ceph/chacra@{{ branch }}#egg=chacra' virtualenv={{ app_home }} changed_when: False - name: create the prod config file - action: template src=../templates/prod.py.j2 dest={{ app_home }}/src/{{ app_name }}/prod.py + sudo: true + template: + src: '../templates/prod.py.j2' + dest: "{{ app_home }}/src/{{ app_name }}/prod.py" - name: create the prod api credentials file + sudo: true template: src: prod_api_creds.py.j2 dest: "{{ app_home }}/src/{{ app_name }}/prod_api_creds.py" + owner: root + group: "{{ app_user }}" + mode: 0640 when: (api_key is defined or api_user is defined) or (app_home_created is defined and app_home_created|changed) - name: install python requirements in virtualenv + sudo: true pip: requirements: "{{ app_home }}/src/{{ app_name }}/requirements.txt" state: present @@ -60,8 +74,9 @@ file: path: "{{ item }}" state: directory - owner: "{{ ansible_ssh_user }}" - group: "{{ ansible_ssh_user }}" + owner: "{{ app_user }}" + group: "{{ app_user }}" + mode: 0755 recurse: yes with_items: - "{{ binary_root }}" @@ -75,10 +90,6 @@ tags: - circus -- include: nginx.yml - tags: - - nginx - # nginx should be up and running by now, there is a bug with Ubuntu 14.04 and # nginx where nginx is using the old init scripts and the 'service' command # returns a zero exit code which ansible interprets as all being OK. diff --git a/deploy/playbooks/roles/common/tasks/postgresql.yml b/deploy/playbooks/roles/common/tasks/postgresql.yml index 70e76afb..5f493191 100644 --- a/deploy/playbooks/roles/common/tasks/postgresql.yml +++ b/deploy/playbooks/roles/common/tasks/postgresql.yml @@ -56,9 +56,13 @@ sudo: yes - name: create the prod_db config file with the db password + sudo: yes template: src: ../templates/prod_db.py.j2 dest: "{{ app_home }}/src/{{ app_name }}/prod_db.py" + owner: root + group: "{{ app_user }}" + mode: 0640 notify: - restart app - restart celery @@ -66,9 +70,13 @@ # this needs to be here because it needs the new db password - name: create the prod alembic.ini file + sudo: yes template: src: ../templates/alembic-prod.ini.j2 dest: "{{ app_home }}/src/{{ app_name }}/alembic-prod.ini" + owner: root + group: "{{ app_user }}" + mode: 0640 - name: check if database for app needs populating # this should be configurable/optional in the playbook @@ -80,6 +88,7 @@ changed_when: "database_is_populated.rc != 0" - name: populate the database for {{ app_name }} + sudo: yes when: "database_is_populated.rc == 1" command: "{{ app_home }}/bin/pecan populate {{ app_home }}/src/{{ app_name }}/prod.py" environment: diff --git a/deploy/playbooks/roles/common/templates/circus.conf b/deploy/playbooks/roles/common/templates/circus.conf index 25e0ae61..11011619 100644 --- a/deploy/playbooks/roles/common/templates/circus.conf +++ b/deploy/playbooks/roles/common/templates/circus.conf @@ -1,3 +1,3 @@ start on filesystem and net-device-up IFACE=lo -setuid {{ ansible_ssh_user }} +setuid {{ app_user }} exec {{ app_home }}/bin/circusd /etc/circus/circus.ini