allanbarcelos / roundcube_2fa
Two-factor authentication (2FA/TOTP) plugin for Roundcube, compatible with Google Authenticator, Microsoft Authenticator and other TOTP apps.
Package info
github.com/allanbarcelos/roundcube-2fa
Type:roundcube-plugin
pkg:composer/allanbarcelos/roundcube_2fa
Requires
- php: >=7.4
- endroid/qr-code: ^4.0
- roundcube/plugin-installer: ~0.1.6 || ~0.2
- spomky-labs/otphp: ^11.0
Requires (Dev)
- phpunit/phpunit: ^10.5 || ^11.0
This package is auto-updated.
Last update: 2026-05-11 17:40:14 UTC
README
A two-factor authentication (2FA) plugin for Roundcube webmail using Time-based One-Time Passwords (TOTP). Compatible with Google Authenticator, Microsoft Authenticator, Authy, and any RFC 6238-compliant app.
Table of Contents
- Features
- Requirements
- Installation
- Database Setup
- Configuration
- Usage
- Security
- Troubleshooting
- Contributing
- License
Features
- TOTP-based 2FA setup per user via QR code
- Backup codes for account recovery (6 single-use codes, cryptographically generated)
- Optional server-side enforcement for all users
- CSRF protection on all sensitive actions
- Automatic database table creation on first use
- Full support for MySQL/MariaDB, PostgreSQL, and SQLite
- Respects Roundcube table prefix configuration
Requirements
| Dependency | Version |
|---|---|
| PHP | >= 7.4 |
| Roundcube | >= 1.5 |
| endroid/qr-code | ^4.0 |
| spomky-labs/otphp | ^11.0 |
Installation
Option A — Composer (recommended)
Run the following command from your Roundcube root directory:
composer require allanbarcelos/roundcube_2fa
Composer will download the plugin into plugins/roundcube_2fa/ and merge all dependencies into the main vendor/ directory automatically.
Option B — Manual
cd /path/to/roundcube/plugins git clone https://github.com/allanbarcelos/roundcube-2fa roundcube_2fa cd roundcube_2fa composer install --no-dev --optimize-autoloader
The target directory must be named
roundcube_2fa(with underscore). Roundcube uses the directory name to locate the plugin class.
Enable the plugin
Add roundcube_2fa to the plugins list in config/config.inc.php:
$config['plugins'] = ['roundcube_2fa'];
That's it. The plugin activates on next page load and creates its database table automatically on first use.
Database Setup
The plugin automatically creates its own roundcube_2fa table on first use — no manual step required for standard installations.
Manual setup
If you prefer to create the table yourself, or if your database user lacks CREATE TABLE privileges, run the file that matches your database engine from the SQL/ directory:
# MySQL / MariaDB mysql -u <user> -p <database> < plugins/roundcube_2fa/SQL/mysql.initial.sql # PostgreSQL psql -U <user> <database> < plugins/roundcube_2fa/SQL/pgsql.initial.sql # SQLite sqlite3 /path/to/roundcube.db < plugins/roundcube_2fa/SQL/sqlite.initial.sql
Table prefix: If your Roundcube installation uses a table prefix (e.g.
rc_), renameroundcube_2fatorc_roundcube_2fain the SQL file before running it. The plugin reads the prefix from your Roundcube configuration automatically.
Configuration
Copy config.inc.php.sample to config.inc.php inside the plugin directory, then adjust the values:
<?php // Force 2FA for all users. Users cannot disable it when this is true. // Default: false $config['roundcube_2fa_force'] = false; // Number of single-use backup codes generated when 2FA is enabled. // Default: 6 $config['roundcube_2fa_backup_codes'] = 6; // Width and height of the QR code image, in pixels. // Default: 200 $config['roundcube_2fa_qr_size'] = 200; // Issuer label shown in the authenticator app alongside the account name. // Default: 'Roundcube' $config['roundcube_2fa_issuer'] = 'Roundcube';
Usage
Enabling 2FA (end user)
- Log in to Roundcube.
- Go to Settings → Two Factor Authentication.
- Click Set up 2FA.
- Scan the QR code with your authenticator app.
- Enter the 6-digit code from the app to confirm.
- Save your backup codes — they are shown only once and cannot be recovered.
Logging in with 2FA active
After entering your username and password, you will be prompted for your TOTP code. Enter the 6-digit code from your authenticator app to complete login.
Using a backup code
If you no longer have access to your authenticator app, enter one of your backup codes in the TOTP field. Each code can only be used once. If all backup codes are exhausted, contact your server administrator.
Disabling 2FA
Go to Settings → Two Factor Authentication and click Disable 2FA. This action immediately revokes the TOTP secret and all remaining backup codes.
Security
- TOTP secrets are stored in a dedicated
roundcube_2fatable, isolated from the Roundcube coreuserstable. - Backup codes are generated with
random_int()(CSPRNG) and stored in the database. Each code is deleted after use. - CSRF tokens are validated on all state-changing actions (enable, disable).
- Session-based credential relay: credentials are held in the server-side session during the 2FA step and never exposed in HTML. The session entry expires after 5 minutes.
- HTTPS is strongly recommended. Without it, TOTP codes transmitted over the network can be intercepted.
Troubleshooting
The 2FA option does not appear in Settings.
Verify that roundcube_2fa is listed in $config['plugins'] and that the plugin directory is named exactly roundcube_2fa. If installed via Composer, confirm that composer require was run from the Roundcube root.
"Invalid code" even with the correct TOTP code. TOTP is time-sensitive. Ensure the server clock is synchronized (e.g. via NTP). A drift of more than 30 seconds will cause verification to fail.
Locked out after losing access to the authenticator app. Use one of your backup codes. If all backup codes are gone, ask your server administrator to run:
UPDATE roundcube_2fa SET enabled = 0, secret = NULL, backup_codes = NULL WHERE user_id = (SELECT user_id FROM users WHERE username = 'your@email.com');
The plugin fails to create the database table.
The database user may lack CREATE TABLE privileges. Run the appropriate SQL file from SQL/ manually using a privileged account.
Contributing
Bug reports and pull requests are welcome. Please open an issue before submitting a pull request for significant changes.
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-change - Commit your changes
- Open a pull request
License
MIT — see LICENSE