In this talk, Barney will be discussing and demonstrating how to:
- Use nginx, Varnish and Apache together in a "SPDY sandwich" to support HTTP 2.0
- Setting up SSL properly to mitigate against attack vectors
- Performance improvements with mod_pagespeed and nginx
- Deploying Drupal sites with Docker containers
Barney is a Technical Team Leader at Inviqa, a Drupal Association member and writes for Techportal on using technologies to improve website performance. He first started using PHP professionally in 2003, and has over seventeen years experience in software development. He is an advocate of Scrum methodology and has an interest in performance optimization, researching and speaking on various techniques to improve user experience through faster load times.
24. Common reasons to
“just log onto the server quickly”
•
server logs in /var/log require privileges to
tail
•
setting permissions on directories
•
Processes require restarting
42. HTTPS without proper ciphers gives
the illusion of security while
providing none
43.
44. Default SSL implementations
Nginx
ssl_protocols SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
Open to Lucky Thirteen attack
Supporting SSLv3 is only required for IE6
Apache 2
SSLProtocol all
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5
45.
46. “Today, only TLS 1.2 with GCM suites offer fully
robust security. All other suites suffer from one
problem or another (e.g, RC4, Lucky 13, BEAST),
but most are difficult to exploit in practice…”
–Ivan Ristic, Qualys
47. “…Because GCM suites are not yet widely
supported, most communication today is carried
out using one of the slightly flawed cipher
suites. It is not possible to do better if you're
running a public web site.”
–Ivan Ristic, Qualys
63. Cross Site Request Forgery
(CSRF)
•
OWASP recommendation
•
Requires a token in the form and a session
token
•
Breaks most reverse proxies without
configuration
64. Am I doing something in my
application that is done better by
the infrastructure or an external
service?
65. OpenResty
•
Nginx bundle
•
Has modules for connecting to Redis,
Drizzle, memcached and many more
•
Has Lua to allow pre and post processing
on requests and responses
70. FIXING CSRF WITH LUA
Header cached in Varnish
OpenResty
Redis
Varnish
Nginx
PHP-FPM
71. FIXING CSRF WITH LUA
•
•
•
OpenResty
Redis
Parses response (regex)!
Finds token placeholder!
Replaces with real token
Varnish
Nginx
PHP-FPM
72. !
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
header_filter_by_lua!
'!
if ngx.var.upstream_http_x_csrf_tokenize then!
! -- the backend requested a CSRF token be set!
! local csrf_cookie_token = nil!
! if ngx.var.cookie_csrf then!
! ! -- they have a cookie, just re-use it!
! ! local csrf_cookie_token = ngx.var.cookie_csrf!
! end!
! ! local resty_random = require "resty.random"!
! ! local str = require "resty.string"!
!
!
!
!
!
!
!
!
if not csrf_cookie_token then!
! -- no valid csrf cookie found, let us make one!
! !
! local cookie_random = resty_random.bytes(16,true)!
! ! !
! ! !
!
!
!
!
! ! !
while cookie_random == nil do!
! -- attempt to generate 16 bytes of!
! -- cryptographically strong (enough) random data!
! cookie_random = resty_random.bytes(16,true)!
end!
73. FIXING CSRF WITH LUA
OpenResty
Varnish
•
Redis
•
Nginx
PHP-FPM
Stores HMAC as value in Redis with
random key “csrf_”
Generates cookie with Redis key as
value
74. !
! ! -- we are about to mess around with the content of the page!
! ! -- so we need to clear this as it will be wrong!
! ! ngx.header.Content_Length = ""! ! ! !
! ! -- set the Cookie for the CSRF token!
! ! ngx.header.Set_Cookie = "csrf=" .. ngx.var.csrf_cookie_token!
! ! ngx.header.tokenize = ngx.var.upstream_http_x_csrf_tokenize!
!
! ! -- now generate one for the form token!
! ! while form_random == nil do!
!
! form_random = resty_random.bytes(16,true)!
!
! ! end!
!
! ! ngx.var.csrf_form_token = str.to_hex(form_random)!
!
! ! local redis = require "redis"!
! ! local client = redis.connect("127.0.0.1", 6379)! !
! ! client:set("csrf_" .. ngx.var.csrf_cookie_token,
ngx.var.csrf_form_token)!
! ! end!
75. FIXING CSRF WITH LUA
Check token on way back in
OpenResty
Redis
Varnish
Nginx
PHP-FPM
76. location @backend {!
! ! # You can't set variables in nginx dynamically, !
# so set this up as empty first!
! ! set $csrf_validate "";!
! ! access_by_lua !
! ! '!
if ngx.req.get_method() == "POST" then!
! -- set up forbidden as default!
! ngx.var.csrf_validate = ngx.HTTP_FORBIDDEN!
! if ngx.var.cookie_csrf then!
! ! ! ! local res = ngx.location.capture("/validate-csrf")!
! ! ! ! if ngx.HTTP_OK == res.status then!
!
! ! ! ngx.req.read_body()!
!
! ! local args = ngx.req.get_post_args()!
!
!
! ! local posted_token = tostring(args["csrf"])!
!
!
! ! if posted_token == res.body then!
!
!
! ! ! ngx.var.csrf_validate = ngx.HTTP_OK!
!
!
! ! end!
!
!
! end!
!
!
!
end!
!
end!
!
';
87. “A litmus test for whether an app has all
config correctly factored out of the code is
whether the codebase could be made open
source at any moment, without
compromising any credentials”
–The Twelve Factor App
88. “The twelve-factor app stores config in
environment variables (often shortened to
env vars or env). Env vars are easy to
change between deploys without changing
any code”
–The Twelve Factor App
89. Put your variables in PHP-FPM
/etc/php/fpm/pools/live.conf
env[db_name]
env[db_host]
env[db_user]
env[db_pass]
env[db_prefix]
=
=
=
=
=
drupal_live
192.168.0.2
liveuser
verysecurepass
drupalcamp_