Drupal Camp Brighton 2015: Ansible Drupal Medicine show
- 4. blue-bag
ANSIBLE & DRUPAL: TOP 10
1. Docker
2. Kubernetes
3. Taiga
4. Apache Mesos
5. OpenStack
6. Ansible
7. ownCloud
8. Apache Hadoop
9. Drupal
10.OpenDaylight
http://opensource.com/business/14/12/
top-10-open-source-projects-2014
Top 10 open source projects in 2014
- 5. blue-bag
SECURITY ISSUES: 2014 TRENDS
CVE-2014-0160
CVE-2014-3566
CVE-2014-8730
CVE-2014-6277
CVE-2014-6278
CVE-2014-7169
CVE-2014-7186
CVE-2014-7187
Shellshock Poodle Heartbleed
SSLv3Bash OpenSSL
Exploits get branding!
- 6. blue-bag
SECURITY ISSUES: SAFE ENOUGH?
Availability of cloud
servers
Ease of setup
Lack of security
practices
Manual exploits
Constellations of
compromised
machines THAT SHOULD DO IT!
- 8. blue-bag
ANSIBLE BASICS
Agentless
Uses SSH
YAML for configuration
Modules
Open source
not just provisioning
“Ansible is a radically simple IT automation system. It handles
configuration-management, application deployment, cloud
provisioning, ad-hoc task-execution, and multinode
orchestration.
- 9. blue-bag
ANSIBLE GOALS
Don’t log into servers
no need for bash scripts
Document build and configuration
(in source control)
Idempotent (idem-what’s-that-again?)
Maintain configuration across inventory
Retain knowledge
- 10. blue-bag
GET THE BOOK!
33% DISCOUNT FOR DCB!
http://leanpub.com/ansible-for-devops/c/
VbhTIPZqGvWT
!
https://leanpub.com/
ansible-for-devops
- 11. blue-bag
ANSIBLE DOCUMENTATION
Github - https://github.com/ansible/ansible
Code and examples
Ansible Documentation - http://docs.ansible.com/
!
Ansible best practices
http://docs.ansible.com/
playbooks_best_practices.html
!
Ansible Galaxy - https://galaxy.ansible.com
- 14. blue-bag
ANSIBLE / VAGRANT
"## demo
"## Vagrantfile
%## hosts
# -*- mode: ruby -*-
# vi: set ft=ruby :
!
VAGRANTFILE_API_VERSION = "2"
!
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.ssh.insert_key = false
config.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", "256"]
end
!
# Application server 1.
config.vm.define "app1" do |app|
app.vm.hostname = "bbdemo-app1.dev"
app.vm.box = "chef/debian-7.4"
app.vm.network :private_network, ip: "192.168.100.120"
end
!
# Application server 2.
config.vm.define "app2" do |app|
app.vm.hostname = "bbdemo-app2.dev"
app.vm.box = "chef/debian-7.4"
app.vm.network :private_network, ip: "192.168.100.121"
end
!
# Database server.
config.vm.define "db" do |db|
db.vm.hostname = "bbdemo-db.dev"
db.vm.box = "chef/debian-7.4"
db.vm.network :private_network, ip: "192.168.100.122"
end
end
# Application servers
[app]
192.168.100.120
192.168.100.121
!
# Database server
[db]
192.168.100.122
!
# Group 'multi' with all servers
[multi:children]
app
db
!
# Variables that will be applied to all
servers"
[multi:vars]
ansible_ssh_user=vagrant
ansible_ssh_private_key_file=~/.vagrant.d
/insecure_private_key
- 15. blue-bag
ANSIBLE BASICS
$ ansible multi -i hosts -a "free -m" -u vagrant
192.168.100.121 | success | rc=0 >>
total used free shared buffers cached
Mem: 244 74 170 0 6 34
-/+ buffers/cache: 32 212
Swap: 767 0 767
!
192.168.100.120 | success | rc=0 >>
total used free shared buffers cached
Mem: 244 74 170 0 6 34
-/+ buffers/cache: 32 212
Swap: 767 0 767
!
192.168.100.122 | success | rc=0 >>
total used free shared buffers cached
Mem: 244 74 170 0 6 34
-/+ buffers/cache: 32 212
Swap: 767 0 767
- 16. blue-bag
ANSIBLE BASICS
"## demo
"## Vagrantfile
"## ansible.cfg
"## hosts
%## log
%## ansible.log
[defaults]
log_path = log/ansible.log
hostfile = ./hosts
…
[multi]
ansible_ssh_user=vagrant
…
$ansible multi -i hosts -a "free -m" -u vagrant
- 17. blue-bag
ANSIBLE BASICS
$ ansible multi -a “date"
!
192.168.100.122 | success | rc=0 >>
Tue Jan 13 10:14:15 UTC 2015
!
192.168.100.121 | success | rc=0 >>
Tue Jan 13 10:14:15 UTC 2015
!
192.168.100.120 | success | rc=0 >>
Tue Jan 13 10:14:15 UTC 2015
- 18. blue-bag
ANSIBLE BASICS
$ansible multi -s -m apt -a "pkg=ntp state=installed_
update_cache=yes"
192.168.100.121 | success >> {
"changed": true,
"stderr": "",
"stdout": "Reading package lists...nBuilding dependency tree...nReading state
information...nThe following extra packages will be installed:n libopts25nSuggested
packages:n ntp-docnThe following NEW packages will be installed:n libopts25 ntpn0
upgraded, 2 newly installed, 0 to remove and 72 not upgraded.nNeed to get 565 kB/638 kB of
archives.nAfter this operation, 1364 kB of additional disk space will be used.nGet:1
http://mirrors.kernel.org/debian/ wheezy/main ntp amd64 1:4.2.6.p5+dfsg-2+deb7u1 [565 kB]
nFetched 565 kB in 13s (40.8 kB/s)nSelecting previously unselected package libopts25.r
n(Reading database ... r(Reading database ... 5%r(Reading database ... 10%r(Reading
database ... 15%r(Reading database ... 20%r(Reading database ... 25%r(Reading
database ... 30%r(Reading database ... 35%r(Reading database ... 40%r(Reading
database ... 45%r(Reading database ... 50%r(Reading database ... 55%r(Reading
database ... 60%r(Reading database ... 65%r(Reading database ... 70%r(Reading
database ... 75%r(Reading database ... 80%r(Reading database ... 85%r(Reading
database ... 90%r(Reading database ... 95%r(Reading database ... 100%r(Reading
database ... 37414 files and directories currently installed.)rnUnpacking libopts25
(from .../libopts25_1%3a5.12-0.1_amd64.deb) ...rnSelecting previously unselected package
ntp.rnUnpacking ntp (from .../ntp_1%3a4.2.6.p5+dfsg-2+deb7u1_amd64.deb) ...rnProcessing
triggers for man-db ...rnSetting up libopts25 (1:5.12-0.1) ...rnSetting up ntp
(1:4.2.6.p5+dfsg-2+deb7u1) ...rnStarting NTP server: ntpd.rn"
}
- 19. blue-bag
ANSIBLE BASICS: THE PLAYBOOK
---
- hosts: all
gather_facts: true
sudo: true
tasks:
- name: NTP | Install NTP
apt: >
name=ntp
state=installed
update_cache=yes
cache_valid_time=3600
"## demo
"## Vagrantfile
"## ansible.cfg
"## hosts
%## log
%## ansible.log
"## playbook.yml
$ ansible-playbook playbook.yml
http://docs.ansible.com/apt_module.html
- 20. blue-bag
ANSIBLE BASICS: ROLES
$ansible-galaxy init 'myrole'
"## myrole
"## README.md
"## defaults
& %## main.yml
"## files
"## handlers
& %## main.yml
"## meta
& %## main.yml
"## tasks
& %## main.yml
"## templates
%## vars
%## main.yml
Use Galaxy Init to create roles
- 21. blue-bag
ANSIBLE BASICS: PROJECT STRUCTURE
https://github.com/iAugur/ansible-playbook-template
"## LICENSE
"## README.md
"## ansible.cfg
"## common
& "## handlers
& & %## main.yml
& %## vars
& %## main.yml
"## group_vars
& %## all.yml
"## host_vars
& %## local.yml
"## hosts
"## log
"## playbook.yml
"## roles
%## base
"## README.md
"## defaults
& %## main.yml
"## files
"## handlers
& %## main.yml
"## meta
& %## main.yml
"## tasks
& %## main.yml
"## templates
%## vars
%## main.yml
Use a template for
Ansible projects.
Common structure
- 22. blue-bag
ANSIBLE BASICS: TESTING
Test play books
$ ansible-playbook --syntax-check --list-tasks main.yml
Check mode
$ansible-playbook main.yml --check
$ansible-playbook main.yml --check --diff
Test against Virtual machines
$ ansible-playbook main.yml -l local
- 23. blue-bag
BASIC SECURITY: FIRST 5
Lock down SSH
Create users and groups
Limit SSH to RSA key:
(no passwords / no root)
Limit to AllowGroups
Update APT - unattended updates security
Configure hostname
Configure IPTables
Configure Fail2ban
- 24. blue-bag
BASIC SECURITY: FIRST 5
Take what we know
Research
Create templates / vars
Consistent across infrastructure
Use tasks to implement
Idempotent
Version controlled
Documented
- 25. blue-bag
FIRST5: SSH - EXAMPLE
"## README.md
"## tasks
& "## main.yml
& %## ssh_config.yml
"## templates
& %## ssh_config.j2
%## vars
%## main.yml
- 26. blue-bag
FIRST5: SSH - EXAMPLE
"## README.md
"## tasks
& "## main.yml
& %## ssh_config.yml
"## templates
& %## ssh_config.j2
%## vars
%## main.yml
# Package generated configuration file
# 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
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes
!
# Lifetime and size of ephemeral version 1 server key
KeyRegenerationInterval 3600
ServerKeyBits 768
# Logging
SyslogFacility AUTH
LogLevel INFO
# Authentication:
LoginGraceTime 120
- 27. blue-bag
FIRST5: SSH - EXAMPLE
"## README.md
"## tasks
& "## main.yml
& %## ssh_config.yml
"## templates
& %## ssh_config.j2
%## vars
%## main.yml
# {{ ansible_managed }}
# See the sshd_config(5) manpage for details
!
# What ports, IPs and protocols we listen for
Port {{ ssh_port }}
# 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
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes
!
# Lifetime and size of ephemeral version 1 server key
KeyRegenerationInterval 3600
ServerKeyBits {{ ssh_server_key_bits }}
# Logging
SyslogFacility AUTH
LogLevel INFO
# Authentication:
LoginGraceTime {{ ssh_login_grace_time }}
- 28. blue-bag
FIRST5: SSH
"## README.md
"## tasks
& "## main.yml
& %## ssh_config.yml
"## templates
& %## ssh_config.j2
%## vars
%## main.yml
# SSH Settings
# optionally change port
ssh_port: 22034
# reduce login grace time from 120 (2 minutes)
ssh_login_grace_time: 20
# increase the server key bit encryption default=768
ssh_server_key_bits: 4096
# control the parallelism
ssh_max_startups: 3:50:10
# control forwarding
ssh_allow_tcp_forwarding: “no”
ssh_allow_x11_forwarding: “no”
- 29. blue-bag
FIRST5: SSH
"## README.md
"## tasks
& "## main.yml
& %## ssh_config.yml
"## templates
& %## ssh_config.j2
%## vars
%## main.yml
---
- name: SSH Config | add ssh config file
template: >
src=ssh_config.j2
dest=/etc/ssh/sshd_config
backup=yes
notify: restart ssh
- 30. blue-bag
BASIC SECURITY: FIRST 5---
- hosts: all
gather_facts: true
sudo: true
!
pre_tasks:
- name: Pretask | Update apt cache
apt: update_cache=yes cache_valid_time=3600
!
- name: Pretask | Run apt-get upgrade
apt: upgrade=dist
roles:
- { role: base , tags: ["base"] }
- { role: ntp , tags: ["ntp"] }
- { role: user, tags: ["user"] }
- { role: ssh , tags: ["ssh"] }
- { role: fail2ban, tags: ["fail2ban"] }
- { role: logwatch , tags: ["logwatch"] }
- { role: exim , tags: ["exim"] }
- { role: geerlingguy.firewall, tags: ["iptables"] }
handlers:
- include: common/handlers/main.yml
Don’t reinvent the wheel
Use Galaxy Roles
where relevant
- 32. blue-bag
BASIC SECURITY: SSL POODLE
- name: Apache security | SSL Poodle update
lineinfile:
dest=/etc/apache2/mods-available/ssl.conf
regexp="{{ item.regexp }}"
line="{{ item.line }}"
backup=yes
with_items:
- {
regexp: "^# enable only secure protocols:",
line: "# enable only secure protocols: TLSv1, but not SSLv2 & SSLv3"
}
- {
regexp: "^SSLProtocol",
line: "SSLProtocol all -SSLv2 -SSLv3"
}
notify: restart apache
tags:
- poodle
- 33. blue-bag
BASIC SECURITY: SSL POODLE
- name: Apache security | SSL Poodle update
template: src=ssl-poodle.conf.j2 dest=/etc/apache2/conf.d/ssl.conf
notify: restart apache
tags:
- poodle
# {{ ansible_managed }}
<IfModule mod_ssl.c>
!
# enable only secure protocols: TLSv1, but not SSLv2 & SSLv3
SSLProtocol all -SSLv2 -SSLv3
!
</IfModule>
SSL-POODLE.CONF.J2
- 34. blue-bag
BASIC SECURITY: DRUPAL SECURITY
Ansible role quickly address
security issues such as
SA-CORE-2014-005
Inventory of Drupal sites
Task to apply patch
Test for vulnerability
Re-use for future patches
- 35. blue-bag
BASIC SECURITY: DRUPAL SECURITY
"## common
& "## handlers
& & %## main.yml
& %## vars
& "## debian.yml
& %## os_default.yml
"## group_vars
& "## all
"## host_vars
& %## local
& %## example.server.net
"## hosts
"## log
& %## ansible.log
"## patch.yml
"## roles
%## SA-CORE-2014-005
"## README.md
"## files
& "## SA-CORE-2014-005-D7.patch
& %## dbtng.patch
"## meta
& %## main.yml
%## tasks
%## main.yml
SA-CORE-2014-005
- 36. blue-bag
BASIC SECURITY: DRUPAL SECURITY
%## SA-CORE-2014-005
"## README.md
"## files
& "## SA-CORE-2014-005-D7.patch
& %## dbtng.patch
"## meta
& %## main.yml
%## tasks
%## main.yml
SA-CORE-2014-005
- 37. blue-bag
BASIC SECURITY: DRUPAL SECURITY---
!
ansible_ssh_host: 123.123.123.123
!
webroot: "/var/www"
!
drupal7_sites:
- {
drupal_docroot: "{{ webroot }}/example.d7.site/live/htdocs”,
vhost_name: "example.d7.site.live"
}
- {
drupal_docroot: "{{ webroot }}/example.d7.site/dev/htdocs",
vhost_name: “example.d7.site.dev"
}
- {
drupal_docroot: "{{ webroot }}/example.d7.site/staging/htdocs",
vhost_name: "example.d7.staging"
}
drupal6_sites:
- {
drupal_docroot: "{{ webroot }}example.d6.site",
vhost_name: "example.d6.site"
}
host_vars: example.server.net
- 38. blue-bag
BASIC SECURITY: DRUPAL SECURITY
---
# tasks file for SA-CORE-2014-005-D7
!
- name: Drupal7 patch | get patch | SA-CORE-2014-005-D7.
get_url:
url: https://www.drupal.org/files/issues/SA-CORE-2014-005-D7.patch
dest: /tmp/SA-CORE-2014-005-D7.patch
!
- name: Drupal7 patch | Apply the patch from the drupal docroot.
shell: "patch -p1 < /tmp/SA-CORE-2014-005-D7.patch chdir={{ item.drupal_docroot }}"
with_items:
- "{{ drupal7_sites }}"
!
- name: Drupal7 patch | Clear Drupal caches.
command: "drush cc all chdir={{ item.drupal_docroot }}"
with_items:
- "{{ drupal7_sites }}"
Role: SA-CORE-2014-005-D7 - main.yml
see blog post: http://www.midwesternmac.com/blogs/jeff-geerling/fixing-drupal-fast-using
- 39. blue-bag
BASIC SECURITY: DRUPAL SECURITY
!
- name: Drupal6 patch | get patch | SA-CORE-2014-005-D7.
copy:
src=dbtng.patch
dest=/tmp/SACORE2014005D6-dbtng.patch owner=root group=root mode=0644
- name: Drupal6 patch | Apply the patch from the drupal docroot.
shell: "patch -p1 < /tmp/SACORE2014005D6-dbtng.patch chdir={{ item.drupal_docroot }}"
with_items:
- "{{ drupal6_sites }}"
tags: D6
Role: SA-CORE-2014-005-D7 - main.yml - (cont..)
- 40. blue-bag
BASIC SECURITY: DRUPAL SECURITY
Subscribe to the security bulletins
Follow key Drupal people on twitter
Harden your Drupal installations
Use version control
Leave Wednesday nights free
- 43. blue-bag
DRUPAL & VHOSTS
Disallow all txt other than robots.txt
Disallow all php other than index.php
Don’t use .htaccess
Migrate all .htaccess to vhosts
Get a static IP
Use custom robots.txt
- 44. blue-bag
NO PHP FILES OTHER THAN INDEX.PHP
<FilesMatch "([^index].php|[^myrobots|robots].*.txt)$">
AuthName "Development"
AuthUserFile /etc/apache2/.htpasswds/passwd
AuthType basic
Require valid-user
Order deny,allow
Deny from all
Allow from 123.123.123.123
Allow from 127.0.0.1
Satisfy Any
</FilesMatch>
- 45. blue-bag
DRUPAL & VHOSTS
Restrict file permissions (640 / 440)
Don’t use .htaccess
Migrate all .htaccess to vhosts
Get a static IP
Use custom robots.txt
Disallow all txt other than robots.txt
Disallow all php other than index.php
- 46. blue-bag
TEST BEFORE RESTART
$ apachectl configtest
Syntax error on line 46 of example.local.conf:
RewriteRule: bad flag delimiters
$ apachectl configtest
$ apachectl graceful
RewriteRule ^ index.php [L, NC]
RewriteRule ^ index.php [L,NC]
46
# If you are on RHEL/CentOS:
$ apachectl -t
$ /etc/init.d/httpd restart
- 47. blue-bag
BASIC SECURITY: DRUPAL SECURITY
Review your logs
Subscribe to the security bulletins
Follow key Drupal people on twitter
Harden your Drupal installations
Use version control
Leave Wednesday nights free
- 48. blue-bag
KEEP YOUR LOGS SLIM
## flag robots.txt requests - allow these to test robot behaviour
SetEnvIf Request_URI "^/robots.txt$" robots-request=log
## flag favicon requests
SetEnvIf Request_URI "^/favicon.ico$" favicon-request=nolog
## set do_not_log if any of the above flags are set
SetEnvIf robots-request nolog do_not_log
SetEnvIf favicon-request nolog do_not_log
## only log if do_not_log is not set
CustomLog /var/www/log/mysite-access.log vcommon env=!do_not_log
- 49. blue-bag
KEEP YOUR LOGS SLIM
## flag robots.txt requests - allow these to test robot behaviour
SetEnvIf Request_URI "^/robots.txt$" robots-request=log
## flag favicon requests
SetEnvIf Request_URI "^/favicon.ico$" favicon-request=nolog
## flag image, Css and JS requests and other static assets
SetEnvIf Request_URI “.(eot|js|css|woff|gif|png|jp(e)g))$” is_static_asset=nolog
## flag cron calls
SetEnvIf Request_URI "^(.*)cron.php$" cron-request=nolog
## flag monitor calls
BrowserMatchNoCase NewRelicPinger monitor-request=nolog
## set do_not_log if any of the above flags are set
SetEnvIf robots-request nolog do_not_log
SetEnvIf favicon-request nolog do_not_log
SetEnvIf image-request nolog do_not_log
SetEnvIf is_static_asset nolog do_not_log
SetEnvIf monitor-request nolog do_not_log
## only log if do_not_log is not set
CustomLog /var/www/log/mysite-access.log vcommon env=!do_not_log
- 51. blue-bag
## {{ ansible_managed }}
!
SecRule RESPONSE_STATUS "@streq 408" "phase:5,t:none,nolog,pass,
setvar:ip.slow_dos_counter=+1, expirevar:ip.slow_dos_counter=60, id:'990002'"
!
SecRule IP:SLOW_DOS_COUNTER "@gt 5" "phase:1,t:none,log,drop, msg:'Client
Connection Dropped due to high number of slow DoS alerts', id:'990003'"
!
SecRule ARGS "ansibletesttoseeifmodsisworking" "phase:1,log,deny,status:
503,msg:'Test Rule',id:'990004'"
!
# Rules to allow good bots with no request header - Don’t do this!!
# SecRule REQUEST_HEADERS:User-Agent "Google|Bing|Yandex" "phase:
1,t:none,allow,nolog,ctl:ruleRemoveById=960015"
# Do this (use Ansible to manage IP list / User-Agents are spoofed)
SecRule REMOTE_ADDR "^66.249.64.165" phase:
1,nolog,allow,ctl:ruleEngine=off,id:960015
!
<LocationMatch "/admin/structure/[pages|views|types]">
SecRuleRemoveById 981173
SecRuleRemoveById 960024
SecRuleRemoveById 981231
</LocationMatch>
BASIC SECURITY: GENERAL SECURITY
./templates/modsecurity_crs_48_local_exceptions.conf.j2
- 52. blue-bag
BASIC SECURITY: GENERAL SECURITY
Mod_security
Drupal specific rule and exclusions
manage exclusions with Ansible
Fail2Ban
Drupal specific actions
IPTables - Whitelists
Remove all unused services
Consider log analysis services
e.g. loggly, paper trail, sumo logic
Know your application ‘surface’
- 53. blue-bag
ANSIBLE & DRUPAL
Put all sites in maintenance mode
(Note: better to use maintenance site and re-point traffic to that so you can still work
on your site on your ip)
Pull latest changes
Use in harmony with Drush
Clear caches and other Drush actions
see https://github.com/jenitehan/drupal_update_check
Extend Drush / Drupal to output JSON
Automate common tasks
- 54. blue-bag
BASIC SECURITY: DRUPAL SECURITY
Consider a platform provider
Subscribe to the security bulletins
Follow key Drupal people on twitter
Harden your Drupal installations
Use version control
Review your logs
Use security best practices
- 55. blue-bag
ANSIBLE & DRUPAL: EXAMPLE 2
Use Case: Commerce site
Product Image updates
Replace the image(s)
Clear the Image Cache/ styles
- 56. blue-bag
ansible_ssh_host: 123.123.123.123
ansible_ssh_user: ansible
drupal_sites:
- “/var/www/mysite/live/htdocs”
- “/var/www/mysite/staging/htdocs"
- "/var/www/mysite/dev/htdocs"
ANSIBLE & DRUPAL: EXAMPLE 2
./host_vars/server.example.com
./main.yml
---
- hosts: all
gather_facts: false
sudo: true
!
roles:
- { role: updateimages , tags: ["updateimages"] }
!
handlers:
- include: common/handlers/main.yml
./hosts
[example]
server.example.com
- 57. blue-bag
---
# vars file for base
files_src_path: “/path/to/local/updated/images”
files_dest_path: “/sites/default/files”
files_to_update:
- “fa9001.jpg"
- “fa9002.jpg"
image_cache_folders:
- “styles/thumbnail/public/product_images"
- "styles/product_gallery/public/product_images"
- "styles/medium_tall/public/product_images"
- "styles/product_full/public/product_images"
ANSIBLE & DRUPAL: EXAMPLE 1
./roles/updateimages/vars/main
---
- name: clear drupal cache
command: "drush cc all chdir={{ item }}"
with_items:
- "{{ drupal_sites }}"
./handlers/main.yml
- 58. blue-bag
- name: Image Update | Products
copy:
src={{ files_src_path }}/{{ item[1] }}
dest={{ item[0] }}/{{ files_dest_path }}/product_images/{{ item[1] }}
owner=www-data
group=www-data
mode:0644
with_nested:
- drupal_sites
- files_to_update
tags: images
notify: clear drupal cache
!
- name: Image Update | Update Cache
file: >
path={{ item[0] }}/{{ files_dest_path }}/{{ item[1] }}/{{ item[2] }}
state=absent
with_nested:
- drupal_sites
- image_cache_folders
- files_to_update
tags: images
notify: clear drupal cache
ANSIBLE & DRUPAL: EXAMPLE 2
./roles/updateimages/tasks/main.yml
- 59. blue-bag
RUN UPDATE
TASK: [updateimages | Image Update | Products] ****************
ok: [server.example.com] => (item=['/var/www/mysite/live/htdocs', 'fa9001.jpg']) =>
{"changed": false, "checksum": "9b36d8209ee8287385b1ce6af48bb033ade468a3", "dest": "/
var/www/mysite/live/htdocs/sites/default/files/product_images/fa9001.jpg", "gid": 33,
"group": "www-data", "item": "fa9001.jpg", "mode": "0644", "owner": "www-data", "path":
“/var/www/mysite/live/htdocs/sites/default/files/product_images/fa9001.jpg", "size":
193018, "state": "file", "uid": 33}
changed: [server.example.com] => (item=['/var/www/mysite/staging/htdocs', 'fa9001.jpg'])
=> {"changed": true, "checksum": "e2d70c097b6fb5900045774e710cfbc9dcadde1a", "dest": "/
var/www/mysite/staging/htdocs/sites/default/files/product_images/fa9001.jpg", "gid": 33,
"group": "www-data", "item": "fa9001.jpg", "md5sum": "10df9698fd4f743fd199372255b15f33",
"mode": "0644", "owner": "www-data", "size": 63598, "src": "/home/georgeb/.ansible/tmp/
ansible-tmp-1420799222.5-262099501965035/source", "state": "file", "uid": 33}
changed: [server.example.com] => (item=['/var/www/mysite/dev/htdocs', 'fa9001.jpg']) =>
{"changed": true, "checksum": "e2d70c097b6fb5900045774e710cfbc9dcadde1a", "dest": "/var/
www/mysite/dev/htdocs/sites/default/files/product_images/fa9001.jpg", "gid": 33,
"group": "www-data", "item": "fa9001.jpg", "md5sum": "10df9698fd4f743fd199372255b15f33",
"mode": "0644", "owner": "www-data", "size": 63598, "src": "/home/georgeb/.ansible/tmp/
ansible-tmp-1420799222.5-262099501965035/source", "state": "file", "uid": 33}
$ ansible-playbook main.yml -l server.example.com -u ansible -K -v --tags "updateimages"
- 60. blue-bag
RUN UPDATE IMAGES PLAY
TASK: [updateimages | Image Update | Update Cache] **************************
ok: [server.example.com] => (item=['thumbnail/public/product_images', 'fa9001.jpg']) => {"changed":
false, "item": ["thumbnail/public/product_images", "fa9001.jpg"], "path": "/var/www/mysite/live/
htdocs/sites/default/files/styles/thumbnail/public/product_images/fa9001.jpg", "state": “absent”}
changed: [server.example.com] => (item=['product_gallery/public/product_images', 'fa9001.jpg']) =>
{"changed": true, "item": ["product_gallery/public/product_images", "fa9001.jpg"], "path": "/var/www/
mysite/live/htdocs/sites/default/files/styles/product_gallery/public/product_images/fa9001.jpg",
"state": "absent"}
changed: [server.example.com] => (item=['medium_tall/public/product_images', 'fa9001.jpg']) =>
{"changed": true, "item": ["medium_tall/public/product_images", "fa9001.jpg"], "path": "/var/www/
mysite/live/htdocs/sites/default/files/styles/medium_tall/public/product_images/fa9001.jpg", "state":
"absent"}
changed: [server.example.com] => (item=['product_full/public/product_images', 'fa9001.jpg']) =>
{"changed": true, "item": ["product_full/public/product_images", "fa9001.jpg"], "path": "/var/www/
mysite/live/htdocs/sites/default/files/styles/product_full/public/product_images/fa9001.jpg",
"state": "absent"}
PLAY RECAP ********************************************************************
server.example.com : ok=2 changed=2 unreachable=0 failed=0
- 62. blue-bag
SOME USEFUL TOOLS
Unicode Code Converter:
http://rishida.net/tools/conversion/
PHP Decoder / Hex Decoder:
http://ddecode.com/phpdecoder/
Permissions Calculator:
http://permissions-calculator.org/
RegEx:
https://regex101.com/#pcre
Network Tools:
CIDR masks etc
http://pingtool.org/
- 63. blue-bag
CONCLUSION / QUESTIONS
For all local
development
use VLAD
http://git.io/DCB-Vlad
For Ansible get the books
https://leanpub.com/
ansible-for-devops
http://www.ansible.com/
ansible-book
Editor's Notes
- Context: Self hosted sites - any server you ssh to and undertake repeatable tasks
if you write shell scripts, scp, have build specs for your servers
take home: sticker and t shirt
- Trends in security exploits in 2014 - Common Vulnerabilities and Exposures (CVE) system
Whereas CVE numbers used to be the preserve of Sysadmins - now they get branded and have gone mainstream - even the Drupal exploit ‘Drupalgeddon’ made it to the BBC web site.
- Although probably not significantly more exploits - probably affect more people.
Previously shared hosting - now everyone can have a server
Easy to get - easy to not secure!
Provider no longer cares as being a VM it is sandboxed from their infrastructure (to a degree)
We are seeing more manual exploits - human captcha on comments etc
more coordinated attacks - wave of similar attacks from set of compromised machines
- As soon as you ‘acquire’ a server / public IP you are under attack
You need to remove root access, secure all ports and lock down the server - then open up for whatever you are going to use it for.
- autodiscovery of variables, handlers, etc
- Apache is extremely intolerant of syntax errors.If you restart and there is an error the web server will stop and not restart.Always test before restarting and use graceful restart to allow existing request to complete.