diff options
author | Eric Wong <e@80x24.org> | 2017-03-08 07:14:07 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2017-03-08 07:14:07 +0000 |
commit | ff13ad38ba9f83e0dd298be451aac7c75145d33b (patch) | |
tree | bc346fd083c976a9b9f43135b7b086afc8351d4f | |
parent | 73e1ce827faad59bfcaff0bc758c8255a5e4f747 (diff) | |
parent | d322345251e15125df896bb8f0a5b53b49a1bf3f (diff) | |
download | unicorn-ff13ad38ba9f83e0dd298be451aac7c75145d33b.tar.gz |
* origin/chroot: Add after_worker_ready configuration option Add support for chroot to Worker#user
-rw-r--r-- | lib/unicorn/configurator.rb | 22 | ||||
-rw-r--r-- | lib/unicorn/http_server.rb | 4 | ||||
-rw-r--r-- | lib/unicorn/worker.rb | 13 |
3 files changed, 34 insertions, 5 deletions
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb index 1e2b6e4..7ed5ffa 100644 --- a/lib/unicorn/configurator.rb +++ b/lib/unicorn/configurator.rb @@ -49,6 +49,9 @@ class Unicorn::Configurator server.logger.error(m) end }, + :after_worker_ready => lambda { |server, worker| + server.logger.info("worker=#{worker.nr} ready") + }, :pid => nil, :preload_app => false, :check_client_connection => false, @@ -172,6 +175,21 @@ class Unicorn::Configurator set_hook(:after_worker_exit, block_given? ? block : args[0], 3) end + # sets after_worker_ready hook to a given block. This block will be called + # by a worker process after it has been fully loaded, directly before it + # starts responding to requests: + # + # after_worker_ready do |server,worker| + # server.logger.info("worker #{worker.nr} ready, dropping privileges") + # worker.user('username', 'groupname') + # end + # + # Do not use Configurator#user if you rely on changing users in the + # after_worker_ready hook. + def after_worker_ready(*args, &block) + set_hook(:after_worker_ready, block_given? ? block : args[0]) + end + # sets before_fork got be a given Proc object. This Proc # object will be called by the master process before forking # each worker. @@ -569,6 +587,10 @@ class Unicorn::Configurator # This switch will occur after calling the after_fork hook, and only # if the Worker#user method is not called in the after_fork hook # +group+ is optional and will not change if unspecified. + # + # Do not use Configurator#user if you rely on changing users in the + # after_worker_ready hook. Instead, you need to call Worker#user + # directly in after_worker_ready. def user(user, group = nil) # raises ArgumentError on invalid user/group Etc.getpwnam(user) diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb index c2086cb..ef897ad 100644 --- a/lib/unicorn/http_server.rb +++ b/lib/unicorn/http_server.rb @@ -15,7 +15,7 @@ class Unicorn::HttpServer :before_fork, :after_fork, :before_exec, :listener_opts, :preload_app, :orig_app, :config, :ready_pipe, :user - attr_writer :after_worker_exit + attr_writer :after_worker_exit, :after_worker_ready attr_reader :pid, :logger include Unicorn::SocketHelper @@ -644,7 +644,7 @@ class Unicorn::HttpServer trap(:USR1) { nr = -65536 } ready = readers.dup - @logger.info "worker=#{worker.nr} ready" + @after_worker_ready.call(self, worker) begin nr < 0 and reopen_worker_logs(worker.nr) diff --git a/lib/unicorn/worker.rb b/lib/unicorn/worker.rb index 6748a2f..e22c1bf 100644 --- a/lib/unicorn/worker.rb +++ b/lib/unicorn/worker.rb @@ -111,9 +111,11 @@ class Unicorn::Worker # In most cases, you should be using the Unicorn::Configurator#user # directive instead. This method should only be used if you need # fine-grained control of exactly when you want to change permissions - # in your after_fork hooks. + # in your after_fork or after_worker_ready hooks, or if you want to + # use the chroot support. # - # Changes the worker process to the specified +user+ and +group+ + # Changes the worker process to the specified +user+ and +group+, + # and chroots to the current working directory if +chroot+ is set. # This is only intended to be called from within the worker # process from the +after_fork+ hook. This should be called in # the +after_fork+ hook after any privileged functions need to be @@ -123,7 +125,7 @@ class Unicorn::Worker # directly back to the caller (usually the +after_fork+ hook. # These errors commonly include ArgumentError for specifying an # invalid user/group and Errno::EPERM for insufficient privileges - def user(user, group = nil) + def user(user, group = nil, chroot = false) # we do not protect the caller, checking Process.euid == 0 is # insufficient because modern systems have fine-grained # capabilities. Let the caller handle any and all errors. @@ -134,6 +136,11 @@ class Unicorn::Worker Process.initgroups(user, gid) Process::GID.change_privilege(gid) end + if chroot + chroot = Dir.pwd if chroot == true + Dir.chroot(chroot) + Dir.chdir('/') + end Process.euid != uid and Process::UID.change_privilege(uid) @switched = true end |