unicorn-lockdown 0.12.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 24ec67b0fb4c2a47aea2652b30a1b99973226d379492fff1a87c1aef3dba5038
4
- data.tar.gz: 84ecb2a8a3a97929e4fc6c960eaee2cab8df0c9f784297e6a3b11ff00c8044f8
3
+ metadata.gz: 0f0b84f88c8502c942f5b15b50bb7ac6946de87ef31ee14cf96e9d71b569b8a3
4
+ data.tar.gz: 69d55260a85368464b5dbb0b9b24120eacb3d9f95f07c4be765f8d913b8e7f2d
5
5
  SHA512:
6
- metadata.gz: 866fcee1a554851025331f856fcb47e3f77f53967a79abda8fc89fd9ead7fd2c390f090338dc3a3047dca22d2b8e7f87595fe5dbc509e5636d825e56c0670544
7
- data.tar.gz: bbec6a5aa7159b05ef7995ca56235f3c08cc001c1fbf6593d2ec1f2c99db457b2d998b01d866f1223b14c58e03e68bef348b0c8e0bbcf213ae38021a3d6da18a
6
+ metadata.gz: 2622fa1ea4b31f117037175273420574269b8f976e905d39a76137aefb4da44e94e13e1ec121db5a9d21fcef901dc3d5fec42434c36d5dd5cc21640d64379131
7
+ data.tar.gz: 032dbedbb2e5eab750fb10ae6f9ef0cb108fdedac239bf3adead2faa637bddfb8613a1d9a865730d449e2d4d6d334f35bab5b762f5b97bf4e946872ebdbf1d63
data/CHANGELOG CHANGED
@@ -1,3 +1,33 @@
1
+ = 1.1.0 (2022-07-18)
2
+
3
+ * Make unveiler still pledge if SimpleCov is loaded, but update pledge promises (jeremyevans)
4
+
5
+ * Fix roda pg_disconnect plugin to correctly error if error_handler is already loaded (jeremyevans)
6
+
7
+ * Avoid SSL error in newer versions of net/smtp when notifying about worker crashes (jeremyevans)
8
+
9
+ * Add flock pledge, needed on Ruby 3.1+ (jeremyevans)
10
+
11
+ = 1.0.0 (2020-11-09)
12
+
13
+ * Require unicorn-lockdown-add -o and -u options, and require options have arguments (jeremyevans)
14
+
15
+ * Switch to starting unicorn master process as application user, drop chroot support, require unveil (jeremyevans)
16
+
17
+ * Remove chrooter library (jeremyevans)
18
+
19
+ * Add unveiler library for testing pledged/unveiled applications, similar to chrooter but smaller (jeremyevans)
20
+
21
+ * Add :master_execpledge option to Unicorn.lockdown, for initial pledge of worker processes (jeremyevans)
22
+
23
+ * Add :master_pledge option to Unicorn.lockdown, for pledging the master process (jeremyevans)
24
+
25
+ = 0.13.0 (2019-07-09)
26
+
27
+ * Add Chrooter.unveil for using unveil in tests (jeremyevans)
28
+
29
+ * Support Unicorn.lockdown :unveil and :dev_unveil options for use of unveil instead of chroot (jeremyevans)
30
+
1
31
  = 0.12.0 (2019-04-29)
2
32
 
3
33
  * Do not reference the rack middleware unicorn loads by default if unicorn is set to not load default middleware (jeremyevans)
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2018 Jeremy Evans
1
+ Copyright (c) 2018-2022 Jeremy Evans
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to
data/README.rdoc CHANGED
@@ -1,22 +1,20 @@
1
1
  = unicorn-lockdown
2
2
 
3
- unicorn-lockdown is a helper library for running Unicorn on OpenBSD in a way
4
- that supports security features such as chroot, privdrop, fork+exec,
5
- and pledge.
6
-
7
- With the configuration unicorn-lockdown uses, the unicorn process executes as root,
8
- and the unicorn master process continues to run as root. The master process
9
- forks worker processes, which re-exec (fork+exec) so that a new memory layout
10
- is used in each worker process. The worker process then loads the application,
11
- after which it chroots to the application's directory, drops root privileges
12
- and then runs as the application user (privdrop), then runs pledge to limit
13
- the allowed system calls to the minimum required to run the application.
3
+ unicorn-lockdown is a helper library for running Unicorn on OpenBSD with pledge,
4
+ unveil, and fork+exec for increased security.
5
+
6
+ With unicorn-lockdown, unicorn should be started as the application user, which
7
+ should be different than the user that owns the application's files. unicorn
8
+ will pledge the master process, then fork worker processes. The worker
9
+ processes will re-exec (fork+exec), then load the application, then set unveil
10
+ to restrict file system access, then pledge to limit the allowed system calls
11
+ at runtime.
14
12
 
15
13
  == Assumptions
16
14
 
17
- unicorn-lockdown assumes you are using OpenBSD 6.2+ with the nginx and
18
- rubyXY-unicorn packages installed, and that you have a unicorn symlink in
19
- the PATH to the appropriate unicornXY executable.
15
+ unicorn-lockdown assumes you are using OpenBSD 6.6+ with the nginx and
16
+ <tt>rubyXY-unicorn</tt> and <tt>rubyXY-pledge</tt> packages installed, and that
17
+ you have a +unicorn+ symlink in the PATH to the appropriate +unicornXY+ executable.
20
18
 
21
19
  It also assumes you have a SMTP server listening on localhost port 25 to
22
20
  receive notification emails of worker crashes, if you are notifying for those.
@@ -33,14 +31,14 @@ the following as root after reading the file and understanding what it does.
33
31
  Briefly, the configuration this uses the following directories:
34
32
 
35
33
  /var/www/sockets :: Stores unix sockets that Unicorn listens on and Nginx uses.
36
- /var/www/requests :: Stores temporary files for each request with request info,
37
- used for crash notifications
34
+ /var/www/request-error-info :: Stores temporary files for each request with request info,
35
+ used for crash notifications
38
36
  /var/log/unicorn :: Stores unicorn log files, one per application
39
37
  /var/log/nginx :: Stores nginx log files, two per application, one for access
40
38
  and one for errors
41
39
 
42
- This adds a _unicorn group that all per-application users will use as their
43
- group, as well as a /etc/rc.d/rc.unicorn file that the per application
40
+ This adds a _unicorn group that all application users will use as one of their
41
+ groups, as well as a /etc/rc.d/rc.unicorn file that the application
44
42
  /etc/rc.d/unicorn_* files will use.
45
43
 
46
44
  === unicorn-lockdown-add
@@ -48,30 +46,38 @@ group, as well as a /etc/rc.d/rc.unicorn file that the per application
48
46
  For each application you want to run with unicorn lockdown, run the following
49
47
  as root, again after reading the file and understanding what it does:
50
48
 
51
- unicorn-lockdown-add
49
+ unicorn-lockdown-add -o $owner -u $user $app_name
52
50
 
53
- Here's an excerpt of the usage:
51
+ Here's the usage:
54
52
 
55
- Usage: unicorn-lockdown-add [options] app_name
53
+ Usage: unicorn-lockdown-add -o owner -u user [options] app_name
56
54
  Options:
57
- -c rackup_file rackup configuration file
58
- -d dir application directory name
59
- -f unicorn_file unicorn configuration file relative to application directory
60
- -o owner operating system application owner
61
- -u user operating system user to run application
62
- --uid uid user id to use if creating the user when -U is specified
63
-
64
- It is a very good idea to specify -o and -u, the other options can be ignored
65
- if you are OK with the default values. The owner (-o) and the user (-u) should be
66
- different. The user is the user the application runs as, and should have very limited
67
- access to the application directory. The owner is the user that owns the application
68
- directory and can make modifications to the application.
55
+ -c RACKUP_FILE rackup configuration file
56
+ -d DIR application directory name
57
+ -f UNICORN_FILE unicorn configuration file relative to application directory
58
+ -o OWNER operating system application owner
59
+ -u USER operating system user to run application
60
+ --uid UID user id to use if creating the user when -U is specified
61
+ -h, -?, --help Show this message
62
+
63
+ The <tt>-o</tt> and <tt>-u</tt> options are required. Default values for other options are:
64
+
65
+ <tt>-c</tt> :: None, Unicorn will use <tt>config.ru</tt> by default.
66
+ <tt>-d</tt> :: Same as +app_name+. The value provided should a relative path under <tt>/var/www</tt>.
67
+ <tt>-f</tt> :: <tt>unicorn.conf</tt>. This file should be relative to +dir+.
68
+ <tt>--uid</tt> :: The uid automatically generated by +useradd+.
69
+
70
+ The owner <tt>-o</tt> and the user <tt>-u</tt> should be different. The user is the user the
71
+ application runs as, and should have read-only access to the application directory,
72
+ other than locations where you want the application user to be able to modify files
73
+ at runtime. The owner is the user that owns the application directory and can make
74
+ modifications to the application.
69
75
 
70
76
  === unicorn-lockdown
71
77
 
72
78
  unicorn-lockdown is the library required in your unicorn configuration
73
79
  file for the application, to handle configuring unicorn to run the app
74
- with chroot, privdrop, fork+exec, and pledge.
80
+ with fork+exec, unveil, and pledge.
75
81
 
76
82
  When you run unicorn-lockdown-add, it will create the unicorn configuration
77
83
  file for the app if one does not already exist, looking similar to:
@@ -80,41 +86,76 @@ file for the app if one does not already exist, looking similar to:
80
86
 
81
87
  Unicorn.lockdown(self,
82
88
  :app=>"app_name",
83
- :user=>"user_name", # Set application user here
84
- :pledge=>'rpath prot_exec inet unix' # More may be needed
85
- :email=>'root' # update this with correct email
89
+
90
+ # Update this with correct email
91
+ :email=>'root',
92
+
93
+ # More pledges may be needed depending on application
94
+ :pledge=>'rpath prot_exec inet unix flock',
95
+ :master_pledge=>'rpath prot_exec cpath wpath inet proc exec',
96
+ :master_execpledge=>'stdio rpath prot_exec inet unix cpath wpath unveil flock',
97
+
98
+ # More unveils may be needed depending on application
99
+ :unveil=>{
100
+ 'views'=>'r'
101
+ },
102
+ :dev_unveil=>{
103
+ 'models'=>'r'
104
+ },
86
105
  )
87
106
 
88
107
  Unicorn.lockdown options:
89
108
 
90
109
  :app :: (required) a short string for the name of the application, used
91
110
  for socket/log file names and in notifications
92
- :user :: (required) the user to drop privileges to
93
- :group :: (optional) the group to use to run the application. On Unicorn
94
- 5.5.0+, can be an array with two entries, the first used as the
95
- process primary group, the second as the owner of the unicorn
96
- log files.
97
- :pledge :: (optional) a pledge string to limit the allowed system calls
98
- after privileges have been dropped
99
111
  :email :: (optional) an email address to use for notifications when the
100
112
  worker process crashes or an unhandled exception is raised by
101
113
  the application or middleware.
114
+ :pledge :: (required) a pledge string to limit the allowed system calls
115
+ after privileges have been dropped
116
+ :master_pledge :: (optional) The string to use when pledging the master process before
117
+ spawning worker processes
118
+ :master_execpledge :: (optional) The pledge string for processes spawned by the master
119
+ process (i.e. worker processes before loading the app)
120
+ :unveil :: (required) a hash of paths to limit file system access, passed
121
+ to +Pledge.unveil+.
122
+ :dev_unveil :: (optional) a hash of paths to limit file system, merged into the :unveil
123
+ option paths if in the development environment. Useful if you are
124
+ allowing more access in development, such as access needed
125
+ for file reloading.
102
126
 
103
127
  With this example pledge:
104
128
 
105
- * rpath is needed to read files in the chrooted file system
129
+ * rpath is needed to read files
106
130
  * prot_exec is needed in most cases
107
131
  * unix is needed for the unix socket to nginx
108
- * inet is not needed in all cases, but in most applications need some form
109
- of network access. pf (OpenBSD's firewall) should be used to limit
110
- access for the application's operating system user to the minimum
111
- necessary access needed.
112
-
113
- unicorn-lockdown has specific support for allowing for emails to be sent
114
- for Unicorn worker crashes (e.g. pledge violations). It also has support
115
- for using rack-unreloader to run your application in development mode
116
- under the chroot while allowing for reloading files if they are modified.
117
- Additionally, unicorn-lockdown modifies unicorn's process status line in a
132
+ * inet is not needed in all cases, but most applications need some form
133
+ of network access, and it is needed by default for emailing about
134
+ exceptions that occur without process crashes. pf (OpenBSD's firewall)
135
+ should be used to limit access for the application's operating system
136
+ user to the minimum necessary access needed.
137
+ * flock is needed in Ruby 3.1+ (not necessarily required in older Ruby versions).
138
+
139
+ With this example master pledge:
140
+
141
+ * rpath is needed to read files
142
+ * prot_exec is needed in most cases
143
+ * cpath and wpath are needed to unlink the request error files
144
+ * inet is needed to send emails for worker crashes
145
+ * proc and exec are needed to spawn worker processes
146
+
147
+ With this examle master exec pledge:
148
+
149
+ * stdio must be added because ruby-pledge doesn't add it automatically
150
+ to execpromises, and Ruby requires it
151
+ * rpath, prot_exec, unix, inet are needed for the worker (see above)
152
+ * cpath and wpath are needed to create the request error files
153
+ * unveil is needed to restrict file system access
154
+
155
+ unicorn-lockdown has specific support for allowing emails to be sent
156
+ for Unicorn worker crashes (e.g. pledge violations) and unhandled
157
+ application exceptions (e.g. pledge violations). Additionally,
158
+ unicorn-lockdown modifies unicorn's process status line in a
118
159
  way that allows it to be controllable via OpenBSD's rcctl program for
119
160
  stopping/starting/reloading/restarting daemons.
120
161
 
@@ -123,7 +164,12 @@ with the expectation of an Nginx limit of 10MB, such that all client
123
164
  requests will be buffered in memory and unicorn will not need to write
124
165
  temporary files to disk. If this limit is not correct for your
125
166
  application, please call client_body_buffer_size after calling
126
- Unicorn.lockdown to set an appropriate limit.
167
+ Unicorn.lockdown to set an appropriate limit. Note that rack still
168
+ creates temporary files for file uploads by default, you'll need to
169
+ configure rack to disallow file uploads if your application does not
170
+ need to accept uploaded files and you don't want file upload attempts
171
+ to cause pledge violations. With Roda, you can use the
172
+ disallow_file_uploads plugin to prevent file upload attempts.
127
173
 
128
174
  When Unicorn.lockdown is used with the :email option, if the worker
129
175
  process crashes, it will email the address using the contents specified
@@ -142,6 +188,8 @@ and then at the top of the route block, do:
142
188
 
143
189
  if defined?(Unicorn) && Unicorn.respond_to?(:write_request)
144
190
  Unicorn.write_request(error_email_content("Unicorn Worker Process Crash"))
191
+ # or
192
+ Unicorn.write_request(error_mail_content("Unicorn Worker Process Crash"))
145
193
  end
146
194
 
147
195
  If you don't have useful information in the request file, an email will
@@ -153,10 +201,20 @@ underlying problem.
153
201
 
154
202
  If you are using PostgreSQL as the database for the application, and using
155
203
  unix sockets to connect the application to the database, if the database
156
- is restarted, the application will no longer be able to connect to it. The
157
- only way to fix this is to kill the worker process and have the master
158
- process spawn a new worker. The roda-pg_disconnect plugin is a plugin
159
- for the roda web toolkit to kill the worker if it detects the database
204
+ is restarted, the application will no longer be able to connect to it unless
205
+ you unveil the path the database socket (stored in /tmp by default). It can
206
+ be a better approach security wise not to allow this, to prevent the
207
+ application from being able to establish new database connections with
208
+ potentially different credentials, as a mitigation in case the server is
209
+ compromised.
210
+
211
+ To allow the application to handle cases where the database is disconnected,
212
+ such as due to a restart of PostgreSQL, you can kill the worker process if
213
+ a disconnect error is detected, and have the master process then spawn a new
214
+ worker.
215
+
216
+ The roda-pg_disconnect plugin is a plugin for the roda web toolkit to kill the
217
+ worker process after handling the connection if it detects the database
160
218
  connection has been lost. This plugin assumes the use of the Sequel database
161
219
  library and postgres adapter with the pg driver.
162
220
 
@@ -165,51 +223,63 @@ In your Roda application:
165
223
  # Sometime before loading the error_handler plugin
166
224
  plugin :pg_disconnect
167
225
 
226
+ To specifically restrict access to the database socket even when access to
227
+ /tmp is allowed, you can unveil the database socket path with no permissions:
228
+
229
+ '/tmp/.s.PGSQL.5432'=>''
230
+
231
+ Note that there are potentially other security issues with unveiling access
232
+ to /tmp beyond granting access to the database server, so it is recommended
233
+ you do not unveil it. If the application needs a directory for temporary
234
+ files (e.g. for handling uploaded files with rack), you can set the +TMPDIR+
235
+ environment variable to an appropriate directory that is writable by the
236
+ application user and not other users, and most web applications will respect
237
+ that (assuming they use the tmpfile/tmpdir libraries in the standard library).
238
+
168
239
  === rack-email_exceptions
169
240
 
170
- rack-email_exceptions is a rack middleware designed to be the first
171
- middleware loaded into applications. It rescues unhandled exceptions
241
+ rack-email_exceptions is a rack middleware designed to wrap all other
242
+ middleware and the application. It rescues unhandled exceptions
172
243
  raised by subsequent middleware or the application itself.
173
-
174
244
  Unicorn.lockdown will automatically setup this middleware if the :email
175
- option is used and the RACK_ENV environment variable is set to production,
176
- such that it wraps the application and all other middleware.
245
+ option is used.
177
246
 
178
247
  It is possible to use this middleware manually:
179
248
 
180
249
  require 'rack/email_exceptions'
181
250
  use Rack::EmailExceptions, "app_name", 'foo@example.com'
182
251
 
183
- === chrooter
252
+ === unveiler
184
253
 
185
- chrooter is a library designed to help with testing applications both in
186
- chroot mode and non-chroot mode. If you are running your application
187
- chrooted, you must support testing while chrooted otherwise it is very
188
- difficult to find problems that only occur when chrooted before putting
189
- the application into production, such as a file being read from outside
190
- the chroot.
254
+ unveiler is a library designed to help with testing applications that
255
+ use pledge and unveil. If you are running your application pledged and
256
+ unveiled, you want your tests to run pledged and unveiled to find
257
+ problems.
191
258
 
192
- chrooter assumes you are using minitest for testing. To use chrooter:
259
+ unveiler assumes you are using minitest for testing. To use unveiler:
193
260
 
194
261
  require 'minitest/autorun'
195
- require 'chrooter'
196
- at_exit{Chrooter.chroot('user_name', 'rpath prot_exec inet unix')}
197
-
198
- If you run your specs as a regular user, it will execute them without
199
- chrooting, but in a way that can still catch some problems that occur
200
- when chrooted. If you run your specs as root, it will chroot to
201
- the current directory after loading the specs, then drop
202
- privileges to the user given (and optionally pledging using the given
203
- pledge string), then run the specs.
262
+ require 'unveiler'
263
+ at_exit do
264
+ Unveiler.pledge_and_unveil('rpath prot_exec inet unix', 'views' => 'r')
265
+ end
204
266
 
205
267
  == autoload
206
268
 
207
- As you'll find out if you try to run your applications with chroot,
208
- autoload is the enemy. Both unicorn-lockdown and chrooter have support
209
- for handling common autoloaded constants in the rack and mail gems.
210
- If you use other gems that use autoload, you'll have to add code that
211
- references the autoloaded constants after the application is loaded but
212
- before chrooting.
269
+ As you'll find out if you try to run your applications with unveil,
270
+ autoload and other forms of runtime requires are the enemy. Both
271
+ unicorn-lockdown and unveiler have support for handling common autoloaded
272
+ constants in the rack and mail gems. If you use other gems that use
273
+ autoload or runtime requires, you'll have to add unveils for the appropriate
274
+ gems:
275
+
276
+ Unicorn.lockdown(self,
277
+ # ...
278
+ :unveil=>{
279
+ 'views' => 'r',
280
+ 'gem-name' => :gem,
281
+ }
282
+ )
213
283
 
214
284
  == Author
215
285
 
@@ -1,224 +1,2 @@
1
1
  #!/usr/bin/env ruby
2
-
3
- require 'etc'
4
- require 'optparse'
5
-
6
- def sh(*args)
7
- puts "Running: #{args.join(' ')}"
8
- system(*args) || raise("Error while running: #{args.join(' ')}")
9
- end
10
-
11
- unicorn = ''
12
- rackup = ''
13
- unicorn_file = 'unicorn.conf'
14
- dir = nil
15
- user = nil
16
- new_user_uid = nil
17
- owner = nil
18
- owner_uid = nil
19
- owner_gid = nil
20
-
21
- options = OptionParser.new do |opts|
22
- opts.banner = "Usage: unicorn-lockdown-add [options] app_name"
23
- opts.separator "Options:"
24
-
25
- opts.on_tail("-h", "-?", "--help", "Show this message") do
26
- puts opts
27
- exit
28
- end
29
-
30
- opts.on("-c rackup_file", "rackup configuration file") do |v|
31
- rackup = "rackup_file=#{v}\n"
32
- end
33
-
34
- opts.on("-d dir", "application directory name") do |v|
35
- dir = v
36
- end
37
-
38
- opts.on("-f unicorn_file", "unicorn configuration file relative to application directory") do |v|
39
- unicorn_file = v
40
- unicorn = "unicorn_conf=#{v}\n"
41
- end
42
-
43
- opts.on("-o owner", "operating system application owner") do |v|
44
- owner = v
45
- ent = Etc.getpwnam(v)
46
- owner_uid = ent.uid
47
- owner_gid = ent.gid
48
- end
49
-
50
- opts.on("-u user", "operating system user to run application") do |v|
51
- user = v
52
- end
53
-
54
- opts.on("--uid uid", "user id to use if creating the user when -U is specified") do |v|
55
- new_user_uid = Integer(v, 10)
56
- end
57
- end
58
- options.parse!
59
-
60
- app = ARGV.shift
61
- dir ||= app
62
- base_dir = dir
63
-
64
- root_id = 0
65
- bin_id = 7
66
- www_id = 67
67
-
68
- www_root = '/var/www'
69
- dir = "#{www_root}/#{dir}"
70
- etc_dir = "#{dir}/etc"
71
- hosts_file = "#{etc_dir}/hosts"
72
- resolv_file = "#{etc_dir}/resolv.conf"
73
- rc_file = "/etc/rc.d/unicorn_#{app.tr('-', '_')}"
74
- nginx_file = "/etc/nginx/#{app}.conf"
75
- unicorn_conf_file = "#{dir}/#{unicorn_file}"
76
- unicorn_log_file = "/var/log/unicorn/#{app}.log"
77
- nginx_access_log_file = "/var/log/nginx/#{app}.access.log"
78
- nginx_error_log_file = "/var/log/nginx/#{app}.error.log"
79
-
80
- # Add application user if it doesn't exist
81
- if user
82
- passwd = begin
83
- Etc.getpwnam(user)
84
- rescue ArgumentError
85
- args = ['/usr/sbin/useradd', '-d', '/var/empty', '-g', '=uid', '-G', '_unicorn', '-L', 'daemon', '-s', '/sbin/nologin']
86
- if new_user_uid
87
- args << '-u' << new_user_uid.to_s
88
- end
89
- args << user
90
- sh(*args)
91
- Etc.getpwnam(user)
92
- end
93
- app_uid = passwd.uid
94
- end
95
-
96
- # Create application directory and chroot directories if they doesn't exist
97
- [dir, "#{dir}/var", "#{dir}/var/www", "#{dir}/etc", "#{dir}/public"].each do |d|
98
- unless File.directory?(d)
99
- puts "Creating #{d}"
100
- Dir.mkdir(d)
101
- File.chmod(0755, d)
102
- File.chown(owner_uid, owner_gid, d) if owner
103
- end
104
- end
105
-
106
- # DRY up file ownership code
107
- setup_file_owner = lambda do |file|
108
- File.chmod(0644, file)
109
- File.chown(owner_uid, owner_gid, file) if owner
110
- end
111
-
112
- # Setup symlink to root so that the same paths work both when
113
- # chrooted and when not chrooted.
114
- chroot_link = "#{dir}#{dir}"
115
- unless File.symlink?(chroot_link)
116
- puts "Creating #{chroot_link}"
117
- File.symlink('/', chroot_link)
118
- end
119
-
120
- # Add /etc/hosts files to chroot
121
- unless File.file?(hosts_file)
122
- puts "Creating #{hosts_file}"
123
- File.binwrite(hosts_file, <<END)
124
- 127.0.0.1 localhost
125
- END
126
- setup_file_owner.call(hosts_file)
127
- end
128
-
129
- # Add /etc/resolv.conf files to chroot
130
- unless File.file?(resolv_file)
131
- puts "Creating #{resolv_file}"
132
- File.binwrite(resolv_file, <<END)
133
- lookup file
134
- END
135
- setup_file_owner.call(resolv_file)
136
- end
137
-
138
- # Setup unicorn configuration file
139
- unless File.file?(unicorn_conf_file)
140
- unicorn_conf_dir = File.dirname(unicorn_conf_file)
141
- unless File.directory?(unicorn_conf_dir)
142
- puts "Creating #{unicorn_conf_dir}"
143
- Dir.mkdir(unicorn_conf_dir)
144
- File.chmod(0755, unicorn_conf_dir)
145
- File.chown(owner_uid, owner_gid, unicorn_conf_dir) if owner
146
- end
147
- puts "Creating #{unicorn_conf_file}"
148
- File.binwrite(unicorn_conf_file, <<END)
149
- require 'unicorn-lockdown'
150
-
151
- Unicorn.lockdown(self,
152
- :app=>#{app.inspect},
153
- :user=>#{user.inspect}, # Set application user here
154
- :pledge=>'rpath prot_exec inet unix', # More may be needed
155
- :email=>'root' # update this with correct email
156
- )
157
- END
158
- setup_file_owner.call(unicorn_conf_file)
159
- end
160
-
161
- # Setup /etc/nginx/* file for nginx configuration
162
- unless File.file?(nginx_file)
163
- puts "Creating #{nginx_file}"
164
- File.binwrite(nginx_file, <<END)
165
- upstream #{app}_unicorn {
166
- server unix:/sockets/#{app}.sock fail_timeout=0;
167
- }
168
- server {
169
- server_name #{app};
170
- access_log #{nginx_access_log_file} main;
171
- error_log #{nginx_error_log_file} warn;
172
- root #{dir}/public;
173
- error_page 500 503 /500.html;
174
- error_page 502 504 /502.html;
175
- proxy_set_header X-Real-IP $remote_addr;
176
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
177
- proxy_set_header Host $http_host;
178
- proxy_redirect off;
179
- add_header X-Content-Type-Options nosniff;
180
- add_header X-Frame-Options deny;
181
- add_header X-XSS-Protection "1; mode=block";
182
- try_files $uri @#{app}_unicorn;
183
- location @#{app}_unicorn {
184
- proxy_pass http://#{app}_unicorn;
185
- }
186
- }
187
- END
188
-
189
- setup_file_owner.call(nginx_file)
190
- end
191
-
192
- # Setup nginx log file
193
- [nginx_access_log_file, nginx_error_log_file].each do |f|
194
- unless File.file?(f)
195
- puts "Creating #{f}"
196
- File.binwrite(f, '')
197
- File.chmod(0644, f)
198
- File.chown(www_id, root_id, f)
199
- end
200
- end
201
-
202
- # Setup unicorn log file
203
- unless File.file?(unicorn_log_file)
204
- puts "Creating #{unicorn_log_file}"
205
- File.binwrite(unicorn_log_file, '')
206
- File.chmod(0640, unicorn_log_file)
207
- File.chown(app_uid, app_uid, unicorn_log_file) if app_uid
208
- end
209
-
210
- # Setup /etc/rc.d/unicorn_* file for daemon management
211
- unless File.file?(rc_file)
212
- puts "Creating #{rc_file}"
213
- File.binwrite(rc_file, <<END)
214
- #!/bin/ksh
215
-
216
- unicorn_app=#{app}
217
- unicorn_dir=#{dir}
218
- #{unicorn}#{rackup}
219
- . /etc/rc.d/rc.unicorn
220
- END
221
-
222
- File.chmod(0755, rc_file)
223
- File.chown(root_id, bin_id, rc_file)
224
- end
2
+ require_relative '../files/unicorn_lockdown_add'