Skip to content

Commit 8bf5a37

Browse files
committed
feat: import legacy adapters from wharf
1 parent 7871298 commit 8bf5a37

7 files changed

Lines changed: 864 additions & 0 deletions

File tree

adapters/drupal/filesystem.ncl

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Drupal Filesystem Policy for Wharf
2+
#
3+
# Drupal has a better separation of concerns than WordPress:
4+
# - Public files in sites/default/files
5+
# - Private files outside web root
6+
# - Config in a separate sync directory
7+
#
8+
# This makes it easier to lock down.
9+
10+
{
11+
adapter = "drupal",
12+
version = "0.1.0",
13+
14+
paths = {
15+
# Core Drupal files (ALWAYS immutable)
16+
immutable = [
17+
"/core",
18+
"/index.php",
19+
"/update.php",
20+
"/web.config",
21+
"/sites/default/settings.php",
22+
"/sites/default/services.yml",
23+
"/.htaccess",
24+
],
25+
26+
# Modules (immutable in production)
27+
modules_immutable = true,
28+
modules_paths = [
29+
"/modules/contrib",
30+
"/modules/custom",
31+
"/sites/all/modules",
32+
],
33+
34+
# Themes (immutable in production)
35+
themes_immutable = true,
36+
themes_paths = [
37+
"/themes/contrib",
38+
"/themes/custom",
39+
"/sites/all/themes",
40+
],
41+
42+
# Public files (writable, no PHP execution)
43+
public_files = {
44+
path = "/sites/default/files",
45+
writable = true,
46+
php_execution = false,
47+
htaccess_override = false,
48+
49+
# Scan for malware
50+
virus_scan = true,
51+
52+
# Block dangerous extensions
53+
blocked_extensions = [
54+
".php", ".php3", ".php4", ".php5", ".phtml",
55+
".exe", ".sh", ".bat", ".cmd",
56+
".htaccess", ".htpasswd",
57+
],
58+
},
59+
60+
# Private files (outside web root)
61+
private_files = {
62+
path = "/var/private/drupal",
63+
writable = true,
64+
php_execution = false,
65+
web_accessible = false,
66+
},
67+
68+
# Config sync directory
69+
config_sync = {
70+
path = "/var/config/drupal/sync",
71+
writable_during_mooring = true,
72+
writable_normally = false,
73+
},
74+
75+
# Temporary files
76+
temp = {
77+
path = "/tmp/drupal",
78+
writable = true,
79+
php_execution = false,
80+
volatile = true,
81+
},
82+
},
83+
84+
# Drupal-specific security settings
85+
security = {
86+
# Disable these features via settings.php
87+
disable_in_production = [
88+
"update_module",
89+
"devel_module",
90+
"views_ui_module",
91+
],
92+
93+
# Enforce these settings
94+
enforce = {
95+
"rebuild_access" = false,
96+
"error_level" = "hide",
97+
},
98+
},
99+
100+
# .htaccess rules
101+
htaccess = {
102+
files_block = '''
103+
<Directory /sites/default/files>
104+
<FilesMatch "\.ph(p[345]?|tml)$">
105+
Require all denied
106+
</FilesMatch>
107+
php_flag engine off
108+
</Directory>
109+
''',
110+
},
111+
}

adapters/drupal/settings.php

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
/**
3+
* Wharf Settings Override for Drupal
4+
*
5+
* Include this file at the end of your settings.php:
6+
* include_once '/path/to/wharf/adapters/drupal/settings.php';
7+
*
8+
* This configures Drupal to work with the Wharf/Yacht security model:
9+
* - Routes database through the Yacht Agent proxy
10+
* - Disables dangerous features in production
11+
* - Enforces read-only filesystem policies
12+
*
13+
* @package Wharf
14+
* @version 0.1.0
15+
*/
16+
17+
// Ensure we're being included from Drupal
18+
if (!defined('DRUPAL_ROOT')) {
19+
die('This file must be included from Drupal settings.php');
20+
}
21+
22+
/**
23+
* Wharf Database Configuration
24+
*
25+
* Override the database connection to route through the Yacht Agent proxy.
26+
*/
27+
$databases['default']['default'] = [
28+
'database' => getenv('DRUPAL_DB_NAME') ?: 'drupal',
29+
'username' => getenv('DRUPAL_DB_USER') ?: 'drupal',
30+
'password' => getenv('DRUPAL_DB_PASS') ?: '',
31+
'host' => '127.0.0.1', // Yacht Agent proxy
32+
'port' => '3307', // Yacht Agent port
33+
'driver' => 'mysql',
34+
'prefix' => '',
35+
'collation' => 'utf8mb4_general_ci',
36+
'init_commands' => [
37+
'isolation_level' => "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED",
38+
],
39+
];
40+
41+
/**
42+
* Wharf Security Settings
43+
*
44+
* These settings lock down Drupal for production use with Wharf.
45+
*/
46+
47+
// Disable update module functionality (updates via Wharf only)
48+
$config['update.settings']['check']['disabled_extensions'] = TRUE;
49+
50+
// Disable file system changes via UI
51+
$settings['file_chmod_directory'] = 0755;
52+
$settings['file_chmod_file'] = 0644;
53+
54+
// Trusted host patterns (prevents host header injection)
55+
// IMPORTANT: Update these to match your actual domains
56+
$settings['trusted_host_patterns'] = [
57+
'^example\.com$',
58+
'^staging\.example\.com$',
59+
'^localhost$',
60+
];
61+
62+
// Disable error display in production
63+
$config['system.logging']['error_level'] = 'hide';
64+
65+
// Private file path (outside web root)
66+
$settings['file_private_path'] = '/var/private/drupal';
67+
68+
// Config sync directory (managed by Wharf)
69+
$settings['config_sync_directory'] = '/var/config/drupal/sync';
70+
71+
// Disable rebuild access (security)
72+
$settings['rebuild_access'] = FALSE;
73+
74+
// Hash salt (should be unique per installation - set via environment)
75+
$settings['hash_salt'] = getenv('DRUPAL_HASH_SALT') ?: 'CHANGE_THIS_TO_A_RANDOM_STRING';
76+
77+
/**
78+
* Wharf-specific flags
79+
*
80+
* These are read by the Yacht Agent to understand Drupal's state.
81+
*/
82+
$settings['wharf'] = [
83+
'enabled' => TRUE,
84+
'adapter_version' => '0.1.0',
85+
'moored' => FALSE, // Set to TRUE during mooring operations
86+
];
87+
88+
/**
89+
* Production performance settings
90+
*/
91+
$config['system.performance']['css']['preprocess'] = TRUE;
92+
$config['system.performance']['js']['preprocess'] = TRUE;
93+
$config['system.performance']['cache']['page']['max_age'] = 3600;
94+
95+
/**
96+
* Disable dangerous modules in production
97+
*
98+
* These modules should only be enabled during development or via Wharf mooring.
99+
*/
100+
$settings['wharf_disabled_modules'] = [
101+
'devel',
102+
'kint',
103+
'webprofiler',
104+
'update',
105+
'dblog', // Use syslog instead
106+
];
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Generic LAMP Filesystem Policy for Wharf
2+
#
3+
# For custom PHP applications that don't use a standard CMS.
4+
# This provides a sensible default that can be customized.
5+
6+
{
7+
adapter = "generic-lamp",
8+
version = "0.1.0",
9+
10+
description = "Generic policy for custom PHP applications",
11+
12+
paths = {
13+
# Web root - immutable by default
14+
web_root = {
15+
path = "/var/www/html",
16+
policy = "read_only",
17+
},
18+
19+
# Common writable directories (customize per app)
20+
writable_dirs = [
21+
{
22+
path = "/var/www/html/uploads",
23+
writable = true,
24+
php_execution = false,
25+
create_if_missing = true,
26+
},
27+
{
28+
path = "/var/www/html/cache",
29+
writable = true,
30+
php_execution = false,
31+
volatile = true,
32+
},
33+
{
34+
path = "/var/www/html/logs",
35+
writable = true,
36+
php_execution = false,
37+
},
38+
{
39+
path = "/tmp/php-sessions",
40+
writable = true,
41+
php_execution = false,
42+
volatile = true,
43+
},
44+
],
45+
46+
# Files to protect
47+
protected_files = [
48+
".env",
49+
"config.php",
50+
"config.ini",
51+
"settings.php",
52+
".htaccess",
53+
".htpasswd",
54+
"composer.json",
55+
"composer.lock",
56+
],
57+
},
58+
59+
# Generic database protection
60+
database = {
61+
# Tables containing user credentials - always lock
62+
lock_patterns = [
63+
".*users.*",
64+
".*admins.*",
65+
".*credentials.*",
66+
".*passwords.*",
67+
".*tokens.*",
68+
".*sessions.*",
69+
".*config.*",
70+
".*settings.*",
71+
],
72+
73+
# Tables likely to be content - allow writes
74+
allow_patterns = [
75+
".*posts.*",
76+
".*comments.*",
77+
".*messages.*",
78+
".*logs.*",
79+
".*cache.*",
80+
],
81+
},
82+
83+
# Generic security headers
84+
headers = {
85+
strip = ["Server", "X-Powered-By"],
86+
add = {
87+
"X-Frame-Options" = "DENY",
88+
"X-Content-Type-Options" = "nosniff",
89+
"X-XSS-Protection" = "1; mode=block",
90+
},
91+
},
92+
}

0 commit comments

Comments
 (0)