Passenger 5.1: a new milestone in robustness, security and efficiency

It’s been a little over a year-and-a-half since we released the first version of Passenger 5, the application server for Ruby, Python, Node.js and Meteor. It brought a large amount of major improvements.

Since then we have introduced many more major improvements. To celebrate this fact, we bumped the minor version number and are happy to announce version 5.1.1! It is the culmination of all the work that has gone into Passenger, with bugfixes, many big and small improvements, and is fully compatible with the 5.0.x line (no breaking changes).

The same period has also seen the growth of the Passenger team, as well as a significant expansion of the Passenger documentation with the introduction of the Passenger Library.

In this blog post we’re looking back at the improvements we’ve introduced in Passenger since 5.0.1. The regular description of changes since 5.0.30 can be found at the end, and includes two notable security fixes.

In an upcoming blog post we will look to the future and describe some of the exciting ideas we have in store for this year, so stay tuned!

A plethora of improvements

There are too many improvements to Passenger since version 5.0 to go into them all in-depth, so we've gathered and categorized them by how they help you to manage and run your application harder, better, faster, stronger.

Minimizing and preventing down time

Passenger has a lot of features for minimizing and preventing downtime in apps, such as rolling restarts and deployment error resistance.

After 5.0.1 we’ve further improved the robustness in challenging situations like running out of memory or crashing application code. Rolling restarts were changed to maintain an even more resource-friendly load profile.

Improvements after 5.0.1
Protection from response body processing crashes
Prevent the connection from stalling if the Ruby handler crashes while processing a Rack response body.
Resource friendly rolling restart (Enterprise)
Passenger Enterprise avoids system overload from processes that use a lot of resources during shutdown by waiting for total process exit before rolling restarting the next process.
Robust log file reopening
Passenger processes now avoid failure to open the log file by re-inheriting from the Watchdog when passenger-config reopen-logs is called.
Robustness when out-of-memory
Improved out-of-memory detection in various subroutines.
Clock time-stepping robustness
Improved Passenger Core robustness against significant system wallclock changes while Passenger is running, by switching to a monotonic clock.

Secure defaults and defense in depth

Passenger does the heavy lifting to provide a secure platform from which you can serve your app with confidence.

In this category one of the most notable improvements after 5.0.1 is the new Passenger security update check. This (optional) feature allows users to be notified in case there are any important Passenger-related security updates so that they can take timely action to keep their systems secure.

Security is high on our priority list and we constantly watch for potential vulnerabilities. For example, when Rails 5 was released, we did a number of tests that revealed a DoS vulnerability. Although Passenger’s design already protects users from this type of issue, we are happy the issue has been fixed in Rails.

Improvements after 5.0.1
Passenger security update check
Daily Passenger security update check to log a warning if there is a newer Passenger version with important security fixes.
Administrative tools can be used without sudo
Admin commands like passenger-status, passenger-config restart-app can be run without sudo, and operate only on apps that are owned by admin command user.
Secure HTTP header support (Node.js)
Our new “Secure HTTP headers” mechanism allows Passenger to send per-request information to the application that cannot be spoofed by the client. Supported in all modes.
CloudLinux LVE and CageFS integration
Users of Passenger + CloudLinux LVE and CageFS benefit from extra security checks and a new control option (PassengerLveMinUid). Contributor: Oleksiy Shchukin, CloudLinux Inc.
Secure error pages
  • New secure defaults for friendly error pages: off unless the environment is development.
  • When friendly error pages are set to off, Passenger never displays any backtraces.
Especially for the Nginx integration mode
Latest stable Nginx
Passenger packages include the latest Nginx stable version, so that you benefit from all the awesome improvements in Nginx as well. Currently this is Nginx 1.10.2 (versus 1.6.0 at the time of Passenger 5.0.1).

Faster & more efficient resource use

Passenger’s design and relentless optimization enables developers and administrators to get the most performance out of their hardware.

With a couple of new options, Passenger helps high-performance servers and applications shine even when under extremely demanding loads. Conditions on a single server such as hundreds of workers, 100K+ RPM with traffic bursts can be handled flawlessly. Another interesting option is that Node.js applications can now be autoscaled; similar to what was already possible for Ruby apps.

Improvements after 5.0.1
Massive concurrency
Three new options to help configure extremely high concurrency: socket_backlog, core_file_descriptor_ulimit and app_file_descriptor_ulimit.
Modernized performance & scaling defaults
  • Speed up disk buffering and request handling with larger mbuf block size (512 to 4096).
  • Handle higher concurrency by default with larger socket backlog size (1024 to 2048).
Fast fail (Node.js, Meteor)
Passenger now signals Node.js and Meteor apps when the client has disconnected during a request so they can stop spending resources on the response.
Dynamic process scaling (Node.js, Meteor)
Node.js and Meteor apps can now benefit from dynamic process scaling with the new force_max_concurrent_requests_per_process option.

Improve development efficiency

Passenger gives developers and administrators super powers so that they can do their jobs more efficiently.

We’ve added a ton of improvements in this category, such as new options and tools for diagnostics, validation and troubleshooting of configurations, applications and connections (e.g. Websockets). Configuration ease and flexibility, as well as maintenance-friendliness have been improved in various ways, like the possibility to configure Passenger Standalone through environment variables or via a refactored configuration template. This makes Passenger integrate better than ever with Heroku, Docker and 12-factor principles.

There are also special improvements like support for the Nginx dynamic module system, installation validation for Passenger + Apache and Docker-friendly logging for Passenger Standalone.

The list below shows the first few items, but you can expand it with the link below that to see all of the improvements.

Improvements after 5.0.1
Analyzing stuck applications or websockets
passenger-status --show=server now reports last_data_send_time and last_data_receive_time which can be used to troubleshoot long-running requests (for example, to see if a websocket heartbeat is stuck).
Diagnostics for stuck processes (Enterprise)
The max_request_time_reached hook allows you to run diagnostics on a process that that took too long to respond to a request.
Thread ID in logging (Enterprise)
When running a Rails app in multithreaded mode, Rails logs are automatically tagged with the current thread number to distinguish logs generated by different threads.
Rails server integration
Passenger can now be started with rails server just like other Rails servers.
Minimum Kernel requirement lifted
RPM packages no longer require kernel 2.6.39 on RHEL 6 / CentOS 6, and are compatible with the latest SELinux changes.
Application restarting convenience & Capistrano
passenger-config restart-app received several improvements:
  • parameter . can be used to restart the app in the current working directory.
  • (Capistrano) new option --ignore-passenger-not-running that allows the command to exit without signaling an error if Passenger is not yet running, or none of the running apps belong to the invoking user.
  • interactive menu allowing you to select the app to restart.

(hide 22 items below)
Load handling statistics
passenger-status --show=server now reports the speed at which new requests are accepted.
Error log improvements
  • More informative error message if a support binary is not found, plus resolution hint.
  • Failed program name is logged rather than its command line (contributed by: paisleyrob).
  • Logging output from app on startup can now be significantly longer.
  • Passenger source code paths in logs are truncated to 3 characters for brevity.
Improved error page look
Revamped the visuals when failing to spawn an application (development & production mode), and Error ID is now also shown in production mode.
Node.js & Meteor clustering troubleshooting
Passenger now reports when you try to use Node.js or Meteor clustering, and tries to continue with just a nonfunctional shim in place, so that if your code uses the clustering APIs your app may still work.
Automation via hooks
All hooks now set the PASSENGER_HOOK_NAME environment variable. This variable is set to the name of the hook that is being called.
API interface extension: force disconnection
There is now an API endpoint for force disconnecting a client: passenger-config admin-command DELETE /server/.json.
Finding downloaded or compiled Passenger components
A new subcommand, passenger-config about support-binaries-dir, can be used in automation scripts.
Especially for the Standalone mode
Configuration from Environment variables
All command line options can now also be specified using environment variables, making Passenger significantly easier to use on Heroku or on systems that follow the 12-factor principle.
Docker-friendly logging
Passenger now accepts /dev/stdout and /dev/stderr as log file path (via --log-file or Passengerfile.json). This is especially useful in Docker containers.
Max request time option (Enterprise)
The --max-request-time option is now supported by Passenger Standalone.
Sticky sessions and envvars for Mass deployment mode (Enterprise)
The sticky_sessions and envvars options in Passengerfile.json are now also supported in mass deployment mode.
Configuration flexibility & convenience
  • The passenger start command now performs a sanity check on the internally generated Nginx configuration file and advises you accordingly when there is a problem.
  • passenger start accepts the --debug-nginx-config configuration option. This option allows you to view the Nginx configuration file that Passenger Standalone generates internally.
  • Raw json environment variables can now be used in Passengerfile.json.
  • Unsupported configuration options set in Passengerfile.json trigger a warning.
Maintenance-friendly configuration template
The Nginx configuration template has been cleaned up. It is significantly easier to edit without breaking compatibility with future versions.
New command line commands to match the power of the config template
The following options from the Nginx configuration template can now also be passed directly to passenger start:
--pool-idle-time, --max-preloader-idle-time, --max-requests, --max-request-queue-size, --memory-limit, --ruby, --nodejs and --python.
Non-interactive mode
The new --auto parameter suppresses prompts for running non-interactively.
RealIP module made available when using the Nginx engine (default)
Relative path support
Support was added for relative values for the pid_file and log_file options in Passengerfile.json.
Especially for the Nginx integration mode
Dynamic module support
Passenger can now be compiled as an Nginx dynamic module. Contributor: Ruslan Ermilov, NGINX Inc.
Index without try_files
The Nginx module now looks for index.html if the path ends in / so that it works intuitively, without needing to use try_files.
Out-of-the-box support for escaped slashes in URI
Passenger now passes to the application the raw URI as sent by the client, as long as Nginx didn't modify the URI (e.g. as part of rewrite rules). This means that escaped slashes (%2F) in the URI now work correctly and out-of-the-box as long as there are no applicable rewrite rules.
Very long request support
Introduces the passenger_read_timeout option for rare cases when server needs more than the default 10 minute timeout. Contributed by pkmiec.
Especially for the Apache integration mode
Autodetect common configuration problems
The installer now validates your Apache configuration file to check for common problems. The validator can also be accessed separately by running passenger-config validate-install --validate-apache2.

Staying ahead of the curve

Passenger embraces modern technologies and multiple platforms to prevent lock-in and to stay ahead of the curve.

As technology moves forward through time, Passenger keeps up. For example, you can use our Passenger APT/RPM packages for the latest couple of versions of Debian, Ubuntu, Red Hat Enterprise Linux and CentOS; which includes the recently released Ubuntu 16.10 and RHEL 7.3. Passenger also supports the newly released JRuby 9.0.0.0 as well as Rails 5 + Action Cable, and a number of smaller improvements like support for IPv6 across all the different integration modes.

Improvements after 5.0.1
Packages for Debian, Ubuntu, CentOS, Red Hat Enterprise Linux
  • Debian 8 "Jessie"
  • Ubuntu 15.04 "Vivid Vervet", Ubuntu 16.04 “Xenial Xerus”, Ubuntu 16.10 “Yakkety Yak”
  • CentOS 6, 7
  • RHEL 6, 7
RHEL 7.3 / SELinux compatibility
The RPM package builder was updated to support (breaking) SELinux changes in RHEL 7.3.
Passing settings to non-bundled Meteor apps
Meteor’s new way of specifying settings for (non-bundled) apps is now supported.
Support SHA256 digests for the Rails asset pipeline
This means that software like the new Sprockets 3.x works seamlessly.
Platform build support
  • OS X 10.11 "El Capitan", macOS 10.12 "Sierra"
  • Debian GNU/kFreeBSD (contributor: stevenc99)
  • IBM power 8 (libev config.sub and config.guess updated)
Support added for JRuby 9.0.0.0
Node.js graceful shutdown
Passenger now calls process.emit('message', 'shutdown') before it shuts down an application process, allowing some compatibility with the Cluster module API.

(hide 8 items below)
Websocket graceful shutdown
With abort_websockets_on_process_shutdown off, applications can cleanly close their websockets when they are being shut down, reducing the number of websocket breaks they need to cope with.
Foreman graceful shutdown
Signal catchers during shutdown allow clean shutdown in Foreman.
HttpV2, realip, addition module
passenger-install-nginx-module and the standalone compiler now add the http v2, realip and addition module flags for Nginx (just like the APT/RPM/autobuilder already had).
Support body.rewind with compression
Supports seek() such that body.rewind works when using Rack middleware that uses Zlib::GzipReader, such as for compressed requests.
XHTML mime type update
The mime type for serving static XHTML files was changed to be recognized by desktop browsers.
Especially for the Standalone mode
Simple Ruby Websocket configuration
Configure Ruby app Websocket urls with a single option: --unlimited-concurrency-path
IPv6 support
The ‘builtin’ engine, recommended engine for reverse proxy setups, now supports IPv6. The ‘nginx’ engine enables ipv6 support by default.
Support application prestarting ('builtin' engine)
Applications can be prestarted using HTTP and HTTPS when using the ‘builtin’ engine.

Changes from 5.0.30 to 5.1.1

For your convenience we've listed the improvements and bugfixes specifically since version 5.0.30 below. This includes two notable vulnerabilities that were addressed in 5.1.0. Version 5.1.0 and 5.1.1 were released in short succession due to a fix for Rails 5.0.1 Action Cable, so we’re covering them both in one blogpost.

CVE-2016-1247

On the 25th of October, an issue with the default permissions in the upstream Nginx APT package was made public. It allows local users with access to the web server user account to gain root privileges via a symlink attack on the error log. The fix has been applied to the Phusion Nginx APT-package.

Predictable tmp File Path Vulnerability

On the 1st of November, Jeremy Evans reported a file overwrite vulnerability caused by a predictable temporary file being written by passenger-install-nginx-module. With access to the system, a user could plant a symlink in /tmp that resulted in a chosen-file overwrite attempt whenever passenger-install-nginx-module was run, using the access rights of the executing user, potentially even with chosen content. Files written to the tmp directory now have randomized path components to fix this vulnerability.

Update: this vulnerability was assigned CVE-2016-10345.

Other bugfixes

Passenger 5.1.0
Fixes a file overwrite vulnerability caused by a predictable temporary file being written by passenger-install-nginx-module. Thanks to Jeremy Evans for reporting this.
Fixes permissions issue on Linux when setting OOM score after lowering privileges. Closes GH-1858.
Fixes unaligned memory access in base64 decoder on platforms that have strict aliasing requirements (non x86/x86_64). Closes GH-1646.
passenger-install-apache-module now suggests the correct apache package on Ubuntu Xenial. Closes GH-1884.
Fixes compilation on Linux when a non-glibc C library is in use. Closes GH-1870.
Fixes an issue where passenger-config couldn't restart an app if the TMPDIR variable was set to /tmp
Especially for the Nginx mode
Updates to APT package builder (Debian & Ubuntu) with fix for www-data to root privilege escalation via log file handling (CVE-2016-1247/USN-3114-1).
Updates to RPM package builder (CentOS & RHEL) with fix for 1.10.x system nginx package overriding the nginx from the Passenger repo. Closes GH-1895.
Especially for the Apache mode
Fixes PassengerShowVersionInHeader option. Thanks to Sebastian Welther for contributing this.
Especially for the Standalone mode
The TempDirToucher will now spend most of its time with reduced privileges, except when it's actively touching files. This allows it to be killed when Passenger is quit in most circumstances. Closes GH-1678.
Fixes starting Passenger as a non-extant user. Closes GH-1849.
Passenger 5.1.1
The precompiled version of the PassengerAgent binary (used for e.g. gem installs) now configures (statically linked) libcurl with system keystore, so that the new security update check can successfully validate certs.
Fixes some false positives (logging) from the new Node and Meteor cluster warning system. Logging is less repetitive and has extra debug info. Closes GH-1905.
Updates the upload-progress module in the Nginx Debian package. The module version that we linked against in 5.1.0 was 0.9.2, but due to a bug in that version the module didn't work.
Especially for Passenger Enterprise
Add missing flying-passenger integration mode to security update check.
Especially for the Apache mode
Introduces a small delay to prevent running the Security Update Checker twice at startup.

Improvements

Passenger 5.1.0
Introduces daily Passenger security update check to warn (error log) if there are newer Passenger versions with important security fixes (describing what was discovered, what is affected, which version has the fix).
Passenger now reports when you try to use Node.js or Meteor clustering, and tries to continue with just a nonfunctional shim in place, so that if your code uses the clustering APIs your app may still work.
Improved look of the error pages for failing to spawn an application (development & production mode), and Error ID is now also shown in production mode.
Ubuntu 16.10 (Yakkety) support.
passenger-install-nginx-module and the standalone compiler now add the http v2, realip and addition module flags for Nginx (just like the APT/RPM/autobuilder already had). Closes GH-1788.
RPM package builder now compatible with (breaking) SELinux change in RHEL 7.3.
RPM packages no longer require kernel 2.6.39 on RHEL 6 / CentOS 6, and are compatible with SELinux changes.
Updates libev config.sub and config.guess to support newer platforms such as the IBM power 8.
Upgrades union_station_hooks_core to version 2.1.2.
Especially for Passenger Enterprise
When running a Rails app in multithreaded mode, Passenger Enterprise automatically tags Rails logs with the current thread number. This makes it possible to distinguish logs generated by different threads.
Especially for the Nginx mode
The preferred Nginx version is now 1.10.2 (previously 1.10.1).
Especially for the Standalone mode
Allows raw json envvars in Passengerfile.json. Closes GH-1837.
Enable ipv6 support by default in builtin nginx. Closes GH-1873.
Make the max_requests option available on the command line as well.
Passenger 5.1.1
The security update check now reports whether libcurl + SSL backend are statically linked to Passenger, in which case the check also needs to warn about relevant OpenSSL vulnerabilities in the linked library.
Increases the allowed line lengths emitted by apps at startup.
Adds support for the unary 'not' operator in the Union Station filter language.
Fixes support for Rails 5.0.1 Action Cable. Specifically, we now support the options argument in the write_nonblock method in hijacked Rack IO sockets.

Installing 5.1.1

Please see the installation guide.

Upgrading to 5.1.1

We strongly advise staying up to date with the latest version.


macOS

Debian

Ubuntu

Heroku

Red Hat

CentOS

Ruby gem

Tarball

Docker

Upgrade notes

  • If you are upgrading from version 4, please see the Passenger 5 upgrade notes for potential caveats.

  • If you are getting a download error during a gem install, ensure you have a version of gem >= 2.2.0 (2013), for instance by running gem install rubygems-update; update_rubygems.

  • If you are using Capistrano and capistrano-passenger, please ensure that capistrano-passenger is upgraded to 0.2.0 or newer to avoid "NoMethodError: undefined method `[]' for nil:NilClass".