## build nginx
cd nginx-source
./configure --prefix=/home/ch/nginx --with-http_ssl_module --with-http_sub_module
make install
## /etc/puppet/rack/config.ru
ch@squigley:/etc/puppet/rack % cat config.ru
# a config.ru, for use with every rack-compatible webserver.
# SSL needs to be handled outside this, though.
# if puppet is not in your RUBYLIB:
$:.push('/home/ch/puppet/lib')
$0 = "puppetmasterd"
#require 'puppet'
# if you want debugging:
ARGV << "--debug"
ARGV << "--rack"
require 'puppet/application/puppetmasterd'
# we're usually running inside a Rack::Builder.new {} block,
# therefore we need to call run *here*.
run Rack::Lint.new(Puppet::Application[:puppetmasterd].run)
## puppet.conf
ch@squigley:/etc/puppet % cat puppet.conf
[puppetmasterd]
ssl_client_header = HTTP_X_SSL_SUBJECT
bindaddress = 'squigley.namespace.at'
storeconfigs = true
dbadapter = sqlite3
dblocation = /var/puppet/storeconfigs.sqlite
manifestdir = /etc/puppet/foo
## nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream unicorn_backend {
server unix:/tmp/my_app.sock fail_timeout=0;
}
ssl on;
ssl_certificate /etc/puppet/ssl/certs/squigley.namespace.at.pem;
ssl_certificate_key /etc/puppet/ssl/private_keys/squigley.namespace.at.pem;
ssl_client_certificate /etc/puppet/ssl/ca_crt.pem;
ssl_ciphers SSLv2:-LOW:-EXPORT:RC4+RSA;
ssl_session_cache shared:SSL:8m;
ssl_session_timeout 5m;
server {
listen 8140;
ssl_verify_client on;
root /var/empty;
access_log /tmp/access-8140.log;
location / {
proxy_pass http://unicorn_backend;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Client-Verify SUCCESS;
proxy_set_header X-SSL-Subject $ssl_client_s_dn;
proxy_set_header X-SSL-Issuer $ssl_client_i_dn;
proxy_read_timeout 65;
}
}
}
## unicorn config
worker_processes 1
working_directory "/etc/puppet/rack"
listen '/tmp/my_app.sock', :backlog => 10
timeout 10
pid "/tmp/my_app.pid"
# combine REE with "preload_app true" for memory savings
# http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
preload_app true
GC.respond_to?(:copy_on_write_friendly=) and
GC.copy_on_write_friendly = true
before_fork do |server, worker|
# the following allows a new master process to incrementally
# phase out the old master process with SIGTTOU to avoid a
# thundering herd (especially in the "preload_app false" case)
# when doing a transparent upgrade. The last worker spawned
# will then kill off the old master process with a SIGQUIT.
old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
end
end
# optionally throttle the master from forking too quickly by sleeping
sleep 1
end
after_fork do |server, worker|
uid, gid = Process.euid, Process.egid
user, group = 'puppet', 'puppet'
target_uid = Etc.getpwnam(user).uid
target_gid = Etc.getgrnam(group).gid
worker.tmp.chown(target_uid, target_gid)
if uid != target_uid || gid != target_gid
Process.initgroups(user, target_gid)
Process::GID.change_privilege(target_gid)
Process::UID.change_privilege(target_uid)
end
# per-process listener ports for debugging/admin/migrations
addr = "127.0.0.1:#{9293 + worker.nr}"
server.listen(addr, :tries => 1, :delay => 5, :tcp_nopush => true)
sleep 3
end
## puppet patch to disable setuid() for rack apps
ch@squigley:~/puppet (git)-[0.25.x] % git diff -a
diff --git a/lib/puppet/application/puppetmasterd.rb b/lib/puppet/application/puppetmasterd.rb
index 9b0bf30..1a8de9b 100644
--- a/lib/puppet/application/puppetmasterd.rb
+++ b/lib/puppet/application/puppetmasterd.rb
@@ -98,17 +98,17 @@ Puppet::Application.new(:puppetmasterd) do
Puppet::SSL::Host.ca_location = :only
end
- if Process.uid == 0
- begin
- Puppet::Util.chuser
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- $stderr.puts "Could not change user to %s: %s" % [Puppet[:user], detail]
- exit(39)
+ unless options[:rack]
+ if Process.uid == 0
+ begin
+ Puppet::Util.chuser
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ $stderr.puts "Could not change user to %s: %s" % [Puppet[:user], detail]
+ exit(39)
+ end
end
- end
- unless options[:rack]
@daemon.server = Puppet::Network::Server.new(:xmlrpc_handlers => xmlrpc_handlers)
@daemon.daemonize if Puppet[:daemonize]
else
## start unicorn
cd /etc/puppet/rack; sudo /var/lib/gems/1.8/bin/unicorn -c /home/ch/unicorn.config