README.MySQL 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. ------------------------ MYSQL/MARIADB SUPPORT ------------------------
  2. When MySQL is enabled, all account info is fetched from a central MySQL
  3. or MariaDB database.
  4. To compile the server with MySQL/MariaDB support, you first have to build and
  5. install the MySQL client libraries. MariaDB is freely available from
  6. https://mariadb.org/ and binary packages are included in many major
  7. distributions. But if you choose a binary form, don't forget to also install
  8. the development packages if they are available separately. For example, on
  9. Debian/Ubuntu systems, the package to install is called
  10. libmariadb-client-lgpl-dev.
  11. Then, configure Pure-FTPd with --with-mysql and your favorite extra gadgets:
  12. ./configure --with-mysql --with-everything
  13. If your MySQL libraries are installed in a special path, you can specify it
  14. like this:
  15. ./configure --with-mysql=/opt/mysql
  16. In this example, headers (like mysql.h) will be searched in
  17. /opt/mysql/include and /opt/mysql/include/mysql, while related libraries
  18. will be searched in /opt/mysql/lib and /opt/mysql/lib/mysql .
  19. Then, install the server as usual:
  20. make install
  21. ------------------------ MYSQL CONFIGURATION FILE ------------------------
  22. Before running the server, you have to create a configuration file. Why a
  23. configuration file instead of simple command-line options? you may ask.
  24. For security reasons, you may want to hide how to connect to your
  25. MySQL server. And as command-line options can be discovered by local users
  26. (with 'ps auxwww' for instance), it's more secure to use a configuration
  27. file for sensitive data. Keep it readable only by root (chmod 600) .
  28. Here's a sample configuration file:
  29. #MYSQLServer localhost
  30. #MYSQLPort 3306
  31. MYSQLSocket /tmp/mysql.sock
  32. MYSQLUser root
  33. MYSQLPassword rootpw
  34. MYSQLDatabase pureftpd
  35. MYSQLCrypt cleartext
  36. MYSQLGetPW SELECT Password FROM users WHERE User="\L"
  37. MYSQLGetUID SELECT Uid FROM users WHERE User="\L"
  38. MYSQLGetGID SELECT Gid FROM users WHERE User="\L"
  39. MYSQLGetDir SELECT Dir FROM users WHERE User="\L"
  40. Have a look at the sample pureftpd-mysql.conf configuration file for
  41. explanations of every keyword.
  42. Save the configuration file anywhere. Let's say /etc/pureftpd-mysql.conf .
  43. Then, you have to run the pure-ftpd command with '-l mysql:' (it's an 'ell'
  44. not a 'one') followed by the path of that configuration file.
  45. Example:
  46. pure-ftpd -l mysql:/etc/pureftpd-mysql.conf -B
  47. You can mix different authentication methods. For instance, if you want to
  48. use system (/etc/passwd) accounts when an account is not found in a MySQL
  49. database, use -l mysql:/etc/pureftpd-mysql.conf -l unix
  50. ------------------------ TABLES STRUCTURES ------------------------
  51. Pure-FTPd is very flexible and users can be stored in any way in SQL tables.
  52. You just have to have fields with the following info:
  53. - The user's login.
  54. - The user's password, hashed using argon2 (argon2id or argon2i), scrypt or
  55. crypt(3). SHA1, MD5, and MySQL's password() format are supported for legacy
  56. reasons, but shouldn't be used any more. Pure-FTPd also accepts the "any"
  57. value for the MySQLCrypt field. With "any", all hash functions are
  58. sequentially tried.
  59. * RECOMMENDATION: Do not use SHA1, MD5, or, obviously, plaintext. Unless your
  60. system provides a decent crypt() function, use a MySQL function to verify
  61. the hashed password or use argon2/scrypt.
  62. - The system uid to map the user to. This can be a numeric id or a user
  63. name, looked up at run-time.
  64. - The system gid (numeric or not) .
  65. - The home directory.
  66. Here's a dump of a simple table to handle this:
  67. CREATE TABLE users (
  68. User VARCHAR(255) BINARY NOT NULL,
  69. Password VARCHAR(255) BINARY NOT NULL,
  70. Uid INT NOT NULL default '-1',
  71. Gid INT NOT NULL default '-1',
  72. Dir VARCHAR(255) BINARY NOT NULL,
  73. PRIMARY KEY (User)
  74. );
  75. Uid and Gid can be char() instead of int() if you want to use names instead
  76. of values.
  77. Then, in the pureftpd-mysql.conf configuration file, you have to provide SQL
  78. templates to fetch the needed info.
  79. Let's take the previous example:
  80. MYSQLGetPW SELECT Password FROM users WHERE User="\L"
  81. MYSQLGetUID SELECT Uid FROM users WHERE User="\L"
  82. MYSQLGetGID SELECT Gid FROM users WHERE User="\L"
  83. MYSQLGetDir SELECT Dir FROM users WHERE User="\L"
  84. For each query:
  85. \L is replaced by the login of a user trying to authenticate.
  86. \I is replaced by the IP address the client connected to.
  87. \P is replaced by the port number the client connected to.
  88. \R is replaced by the remote IP address the client connected from.
  89. \D is replaced by the remote IPv4 address, as a long decimal number.
  90. You can mix all of these to store info in various tables. For instance, with
  91. \I, you can have a different table for every domain, so that joe@domain1
  92. won't be the same account as joe@domain2 . And with \R, you can restrict
  93. one account to one specific address.
  94. Multiple statements can be used using a semicolon (";") as a delimiter.
  95. Please note that a login can only contain common characters: A...Z, a...z,
  96. 0...9, -, ., _, space, :, @ and ' . For security purposes, other characters
  97. are forbidden.
  98. You can also remove uid and gid fields in your tables and use default
  99. values instead (thus saving useless lookups) . Two directives are
  100. useful to serve that purpose: MYSQLDefaultUID and MYSQLDefaultGID.
  101. Obvious example:
  102. MYSQLDefaultUID 1000
  103. MYSQLDefaultGID 1000
  104. Using these directives overrides MYSQLGetUID and MYSQLGetGID.
  105. ------------------------ ARGON2 ------------------------
  106. Password hashed with argon2i and argon2id can be used, provided that pure-ftpd
  107. was linked to libsodium.
  108. They are expected to be provided as a string, as returned by the
  109. crypto_pwhash_str() function or by its bindings.
  110. ------------------------ SCRYPT ------------------------
  111. Password hashed with scrypt can be used, provided that pure-ftpd was linked to
  112. libsodium.
  113. They are expected to be provided in escrypt format, as returned by the
  114. crypto_pwhash_scryptsalsa208sha256_str() function or by its bindings.
  115. For example, the string $7$C6..../....YzvCLmJDYJpH76BxlZB9fCpCEj2AbGQHoLiG9I/VRO1$/enQ.o1BNtmxjxNc/8hbZq8W0JAqR5YpufJXGAdzmf3
  116. would verify the password "test".
  117. ------------------------ PER-USER SETTINGS ------------------------
  118. Individual settings can be set for every user, using optional queries.
  119. - MySQLGetQTAFS is the maximal number of files a user can store in his home
  120. directory.
  121. Example:
  122. MySQLGetQTAFS SELECT QuotaFiles FROM users WHERE User="\L"
  123. - MySQLGetQTASZ is the maximal disk usage, in Megabytes.
  124. Example:
  125. MySQLGetQTASZ SELECT QuotaSize FROM users WHERE User="\L"
  126. - MySQLGetRatioUL and MySQLGetRatioDL are optional ratios.
  127. Example:
  128. MySQLGetRatioUL SELECT ULRatio FROM users WHERE User="\L"
  129. MySQLGetRatioDL SELECT DLRatio FROM users WHERE User="\L"
  130. - MySQLGetBandwidthUL and MySQLGetBandwidthDL are optional upload and
  131. download bandwidth restrictions. Returned values should be in KB/s.
  132. Example:
  133. MySQLGetBandwidthUL SELECT ULBandwidth FROM users WHERE User="\L"
  134. MySQLGetBandwidthDL SELECT DLBandwidth FROM users WHERE User="\L"
  135. - MySQLForceTildeExpansion is yet another optional feature, to enable "~"
  136. expansion in paths. 0 disables it (default), 1 enables it. Only enable this
  137. if real (system) users and virtual (MySQL) users match. In all other cases,
  138. don't enable it blindly.
  139. ------------------------ TRANSACTIONS ------------------------
  140. If you upgraded your tables to transaction-enabled tables, you can configure
  141. Pure-FTPd to take advantage of transactions. That way, you can be sure that
  142. all info parsed by the server is complete even if you're updating it at the
  143. same time.
  144. To enable transactions, add this line:
  145. MySQLTransactions On
  146. Don't enable transactions on tables that still are in ISAM or MyISAM
  147. formats. Transactions are only working with newer backends (Gemini, InnoDB,
  148. BerkeleyDB...) and in recent MySQL versions.
  149. ------------------------ STORED PROCEDURES ------------------------
  150. Mike Goins says:
  151. To get pure-ftp to use a MySQL 5 stored procedure, use statements like:
  152. MYSQLGetDir CALL get_path_from_name("\L")
  153. instead of
  154. MYSQLGetDir SELECT user_dir FROM user WHERE user_name="\L"
  155. Note that this requires the type of Stored Procedure that returns a result set
  156. in a single call as opposed to the two call method:
  157. CALL sp('value', @a); SELECT @a
  158. ------------------------ ANONYMOUS USERS ------------------------
  159. If you want to accept anonymous users on your FTP server, you don't need to
  160. have any 'ftp' user in the MySQL directory. But you need to have a system
  161. 'ftp' account on the FTP server.
  162. ------------------------ ROOT USERS ------------------------
  163. If a MySQL user entry has a root (0) uid and/or gid, Pure-FTPd will refuse
  164. to log them in.
  165. Without this preventive restriction, if your MySQL server ever gets
  166. compromised, the attacker could also easily compromise the FTP server.
  167. Security barriers are also implemented to avoid bad implications if wrong
  168. data types (eg. binary blobs instead of plain text) are fetched with SQL
  169. queries.