Adoptable Cookbooks List

Looking for a cookbook to adopt? You can now see a list of cookbooks available for adoption!
List of Adoptable Cookbooks

Supermarket Belongs to the Community

Supermarket belongs to the community. While Chef has the responsibility to keep it running and be stewards of its functionality, what it does and how it works is driven by the community. The chef/supermarket repository will continue to be where development of the Supermarket application takes place. Come be part of shaping the direction of Supermarket by opening issues and pull requests or by joining us on the Chef Mailing List.

Select Badges

Select Supported Platforms

Select Status


onddo_proftpd (4) Versions 2.0.0

Installs and Configures ProFTPD ftp server.

cookbook 'onddo_proftpd', '= 2.0.0', :supermarket
cookbook 'onddo_proftpd', '= 2.0.0'
knife supermarket install onddo_proftpd
knife supermarket download onddo_proftpd
Quality 100%


Cookbook Version
Dependency Status
Code Climate
Build Status

Chef Cookbook to install and configure the ProFTPD FTP server.


Supported Platforms

This cookbook has been tested on the following platforms:

  • Amazon
  • CentOS
  • Debian
  • Fedora
  • RedHat
  • Ubuntu

Please, let us know if you use it successfully on any other platform.

Required Cookbooks

Required Applications

  • Ruby >= 1.9.3


Attribute Default Description
node['proftpd']['conf_files_user'] 'root' System user to own the ProFTPD configuration files.
node['proftpd']['conf_files_group'] 'root' System group to own the ProFTPD configuration files.
node['proftpd']['conf_files_mode'] '00640' ProFTPD configuration files system file mode bits.
node['proftpd']['module_packages'] calculated ProFTPD system packages required to use some modules. This is distribution specific and usually there is no need to change it.
node['proftpd']['conf'] calculated ProFTPD configuration as key/value multi-level Hash.



Installs and Configures ProFTPD.


Installs ProFTPD ohai plugin. Called by the ::default recipe.


Including in a Cookbook Recipe

You can simply include it in a recipe:

# from a recipe
include_recipe 'onddo_proftpd'

Don't forget to include the onddo_proftpd cookbook as a dependency in the metadata.

# metadata.rb

depends 'onddo_proftpd'

Including in the Run List

Another alternative is to include the default recipe in your Run List.

  "name": "",
  "run_list": [

Changing the Configuration

Configuration directives will be created inside the proftpd.conf file. Other configuration files will be ignored unless included. By default, only the conf.d directory will be included:

node.default['proftpd']['conf']['include'] = %w{/etc/proftpd/conf.d}

All the configuration for the proftpd.conf file is read from the node['proftpd']['conf'] attribute.

Under this namespace, you can set configuration directives using both the CamelCase and the_underscore syntax.

For example, using the underscore syntax:

node.default['proftpd']['conf']['use_ipv6'] = false
node.default['proftpd']['conf']['ident_lookups'] = false
node.default['proftpd']['conf']['server_name'] = 'My FTP server'

include_recipe 'onddo_proftpd'

Using the camelcase syntax:

node.default['proftpd']['conf']['UseIPv6'] = false
node.default['proftpd']['conf']['IdentLookups'] = false
node.default['proftpd']['conf']['ServerName'] = 'My FTP server'

include_recipe 'onddo_proftpd'

The cookbook will try to do the correct conversion from underscore to camelcase including some edge cases, like for example UseIPv6 (you don't need to use use_i_pv6, use_ipv6 is OK also).

In any case, use the syntax you prefer.

Block Directives

Some of the directives set in the attributes will be treated in a special way:

  • Global or global: will create a <Global> block, must contain an Array of directives.
  • Directory or directory: will create a <Directory> block, must contain a Hash of directives.
  • VirtualHost or virtual_host: will create a <VirtualHost> block, must contain a Hash of directives.
  • Anonymous or anonymous: will create a <Anonymous> block, must contain a Hash of directives.
  • Limit or limit: will create a <Limit> block, must contain a Hash of directives.
  • IfAuthenticated or if_authenticated: will create a <IfAuthenticated> block, must contain an Array of directives.
  • IfModule or if_module: will create a <IfModule> block, must contain a Hash of directives.
  • IfClass or if_class: will create a <IfClass> block, must contain a Hash of directives.
  • IfGroup or if_group: will create a <IfGroup> block, must contain a Hash of directives.
  • IfUser or if_user: will create a <IfUser> block, must contain a Hash of directives.

See the examples below to learn how to use them.

Valueless Directives

If the directive has no value, like AllowAll or DenyAll, you set it to nil to enable it. For example:

node.default['proftpd']['conf']['anonymous']['~ftp']['directory']['*']['limit']['write']['deny_all'] = nil
node.default['proftpd']['conf']['anonymous']['~ftp']['directory']['incoming']['limit']['read write']['deny_all'] = nil
node.default['proftpd']['conf']['anonymous']['~ftp']['directory']['incoming']['limit']['stor']['allow_all'] = nil

Configuring a Module

The best way to set a module configuration is to use the <IfModule> configuration directive. For example:

# mod_ctrls_admin.c module
node.default['proftpd']['conf']['if_module']['ctrls_admin']['admin_controls_engine'] = false

You can use the full module name if you prefer (mod_*.c):

node.default['proftpd']['conf']['if_module']['mod_ctrls_admin.c']['admin_controls_engine'] = false

You can also use the special ['prefix'] key to save putting a prefix in all the configuration directives:

# Create a <IfModule> directive block
node.default['proftpd']['conf']['if_module']['ctrls']['prefix'] = 'Controls'
node.default['proftpd']['conf']['if_module']['ctrls']['engine'] = false # ControlsEngine
node.default['proftpd']['conf']['if_module']['ctrls']['max_clients'] = 2 # ControlsMaxClients
node.default['proftpd']['conf']['if_module']['ctrls']['log'] = '/var/log/proftpd/controls.log' # ControlsLog
node.default['proftpd']['conf']['if_module']['ctrls']['interval'] = 5 # ControlsInterval
node.default['proftpd']['conf']['if_module']['ctrls']['socket'] = '/var/run/proftpd/proftpd.sock' # ControlsSocket

This prefix will only be applied under the current block (<IfModule> in this example), excluding deeper blocks under ['ctrls'], like for example ['ctrls']['directory']['*'][...].

Enabling SSL/TLS

In the following example, we are using the ssl_certificate cookbook to create the certificate:

# TLS configuration
cert = ssl_certificate 'proftpd' do
  common_name node['fqdn'] || ''
node.default['proftpd']['conf']['if_module']['tls']['prefix'] = 'TLS'
node.default['proftpd']['conf']['if_module']['tls']['engine'] = true
node.default['proftpd']['conf']['if_module']['tls']['log'] = '/var/log/proftpd/tls.log'
# Support both SSLv3 and TLSv1
node.default['proftpd']['conf']['if_module']['tls']['protocol'] = 'SSLv3 TLSv1'
# Are clients required to use FTP over TLS when talking to this server?
node.default['proftpd']['conf']['if_module']['tls']['required'] = false
node.default['proftpd']['conf']['if_module']['tls']['rsa_certificate_file'] = cert.cert_path
node.default['proftpd']['conf']['if_module']['tls']['rsa_certificate_key_file'] = cert.key_path
# Authenticate clients that want to use FTP over TLS?
node.default['proftpd']['conf']['if_module']['tls']['verify_client'] = false
# Avoid CA cert with relaxed session use for some clients (e.g. FireFtp)
node.default['proftpd']['conf']['if_module']['tls']['options'] = 'NoCertRequest EnableDiags NoSessionReuseRequired'
# Allow SSL/TLS renegotiations when the client requests them, but
# do not force the renegotations.  Some clients do not support
# SSL/TLS renegotiations; when mod_tls forces a renegotiation, these
# clients will close the data connection, or there will be a timeout
# on an idle data connection.
node.default['proftpd']['conf']['if_module']['tls']['renegotiate'] = 'none'

include_recipe 'onddo_proftpd'

Creating a VirtualHost

node.default['proftpd']['conf']['virtual_host'][''] = {
  'server_admin' => '',
  'server_name' => 'Big FTP Archive',
  'transfer_log' => '/var/log/proftpd/',
  'max_login_attempts' => 3,
  'require_valid_shell' => false,
  'default_root' => '/tmp',
  'allow_overwrite' => true,

include_recipe 'onddo_proftpd'

Creating an Anonymous FTP

user 'ftp' do
  system true
  shell '/bin/false'
  supports :manage_home => true

node.default['proftpd']['conf']['require_valid_shell'] = false

node.default['proftpd']['conf']['anonymous']['~ftp'] = {
  'user' => 'ftp',
  'group' => 'nogroup',
  'user_alias' => 'anonymous ftp',
  'dir_fake_user' => 'on ftp',
  'dir_fake_group' => 'on ftp',
  'require_valid_shell' => false,
  'max_clients' => 10,
  'display_login' => 'welcome.msg',
  'display_chdir' => '.message',
  'directory' => {
    '*' => {
      'limit' => {
        'write' => {
          'deny_all' => nil,
    'incoming' => {
      'umask' => '022 022',
      'limit' => {
        'read write' => {
          'deny_all' => nil,
        'stor' => {
          'allow_all' => nil,




Please do not hesitate to open an issue with any questions or problems.




License and Author

Author: Xabier de Zuazo (
Copyright: Copyright (c) 2014, Onddo Labs, SL. (
License: Apache License, Version 2.0
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
See the License for the specific language governing permissions and
limitations under the License.

Dependent cookbooks

ohai >= 0.0.0
yum-epel >= 0.0.0

Contingent cookbooks

There are no cookbooks that are contingent upon this one.

onddo_proftpd CHANGELOG

This file is used to list changes made in each version of the onddo_proftpd cookbook.

2.0.0 (2014-10-24)

  • Update Warning: Ruby <= 1.9.2 compatibilty drop. Ruby >= 1.9.3 is required.
  • Create an empty modules.conf file to fix Debian updates (fixes issue #5, thanks Denny Schäfer for reporting).
  • Fix all RuboCop offenses (big libraries refactor).
  • Update to use Serverspec 2.
  • Update to use ChefSpec 4.1.
  • Integrate tests with should_not gem.
  • .kitchen.yml: use one line array to include apt in the Run List.
  • Use a more complete Berksfile template.
  • Rakefile: add documentation link.
  • Add Guardfile.
  • Homogenize license headers.
    • Add a missing dot in a recipe description.
    • Use single quotes in examples.
    • Use markdown tables.
    • Add Code Climate badge.

1.0.0 (2014-09-28)

  • Update Warning: Disabled some modules by default to fix Ubuntu 10 compatibility: exec, shaper, sftp and sftp_pam.
  • Update Warning: Set DefaultAddress configuration option to avoid some start errors (related with issue #2, thanks @fervic for reporting).
  • Fixed integration tests for CentOS 5.
  • Fix Ubuntu 14.04 support (monkey-patch for bug 1293416, fixes issue #2, thanks @themasterchef for reporting).
  • Fix FC034: Unused template variables.
  • kitchen.yml: Added more platforms to test.
  • removed yum from run list.
  • Gemfile updated and improved using groups.
  • Berksfile cleaned and updated to Berkshelf 3.
  • Added some basic Serverspec tests.
  • Added ChefSpec tests and a Rakefile.
  • test/kitchen/cookbooks directory moved to test/cookbooks.
  • Added LICENSE file.
  • Added travis.yml file.
    • Added badges: cookbook version, gemnasium and travis-ci.
    • Updated cookbook links to point to Supermarket.
    • Separated into multiple files.
    • Some small improvements.
  • Added RedHat as supported platform.
  • Some integration tests fixes to support more platforms.
  • Integration tests improved: added onddo_proftpd_test::attrs recipe.
  • Added a Vagrantfile and its documentation.

0.1.0 (2014-04-25)

  • Initial release of onddo_proftpd.

Foodcritic Metric

2.0.0 passed this metric