Skip to content

Commit 1db4fa8

Browse files
Refactor environment loading and handling for FrankenPHP (#397)
1 parent 329568f commit 1db4fa8

File tree

15 files changed

+77
-55
lines changed

15 files changed

+77
-55
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,25 +39,25 @@ Prerequisites:
3939

4040
##### x86_64
4141
```
42-
rpm -Uvh --oldpackage https://github.com/AikidoSec/firewall-php/releases/download/v1.5.1/aikido-php-firewall.x86_64.rpm
42+
rpm -Uvh --oldpackage https://github.com/AikidoSec/firewall-php/releases/download/v1.5.2/aikido-php-firewall.x86_64.rpm
4343
```
4444

4545
##### arm64 / aarch64
4646
```
47-
rpm -Uvh --oldpackage https://github.com/AikidoSec/firewall-php/releases/download/v1.5.1/aikido-php-firewall.aarch64.rpm
47+
rpm -Uvh --oldpackage https://github.com/AikidoSec/firewall-php/releases/download/v1.5.2/aikido-php-firewall.aarch64.rpm
4848
```
4949

5050
#### For Debian-based Systems (Debian, Ubuntu)
5151

5252
##### x86_64
5353
```
54-
curl -L -O https://github.com/AikidoSec/firewall-php/releases/download/v1.5.1/aikido-php-firewall.x86_64.deb
54+
curl -L -O https://github.com/AikidoSec/firewall-php/releases/download/v1.5.2/aikido-php-firewall.x86_64.deb
5555
dpkg -i -E ./aikido-php-firewall.x86_64.deb
5656
```
5757

5858
##### arm64 / aarch64
5959
```
60-
curl -L -O https://github.com/AikidoSec/firewall-php/releases/download/v1.5.1/aikido-php-firewall.aarch64.deb
60+
curl -L -O https://github.com/AikidoSec/firewall-php/releases/download/v1.5.2/aikido-php-firewall.aarch64.deb
6161
dpkg -i -E ./aikido-php-firewall.aarch64.deb
6262
```
6363

docs/aws-elastic-beanstalk.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
```
55
commands:
66
aikido-php-firewall:
7-
command: "rpm -Uvh --oldpackage https://github.com/AikidoSec/firewall-php/releases/download/v1.5.1/aikido-php-firewall.x86_64.rpm"
7+
command: "rpm -Uvh --oldpackage https://github.com/AikidoSec/firewall-php/releases/download/v1.5.2/aikido-php-firewall.x86_64.rpm"
88
ignoreErrors: true
99
1010
files:

docs/fly-io.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Create a script to install the Aikido PHP Firewall during deployment:
3232
#!/usr/bin/env bash
3333
cd /tmp
3434

35-
curl -L -O https://github.com/AikidoSec/firewall-php/releases/download/v1.5.1/aikido-php-firewall.x86_64.deb
35+
curl -L -O https://github.com/AikidoSec/firewall-php/releases/download/v1.5.2/aikido-php-firewall.x86_64.deb
3636
dpkg -i -E ./aikido-php-firewall.x86_64.deb
3737
```
3838

docs/laravel-forge.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ You can get your token from the [Aikido Security Dashboard](https://help.aikido.
88

99
Go to "Commands" and run the following by replacing the sudo password with the one that Forge displays when the server is created:
1010
```
11-
curl -L -O https://github.com/AikidoSec/firewall-php/releases/download/v1.5.1/aikido-php-firewall.x86_64.deb && echo "YOUR_SUDO_PASSWORD_HERE" | sudo -S dpkg -i -E ./aikido-php-firewall.x86_64.deb && echo "YOUR_SUDO_PASSWORD_HERE" | sudo -S service php8.4-fpm restart
11+
curl -L -O https://github.com/AikidoSec/firewall-php/releases/download/v1.5.2/aikido-php-firewall.x86_64.deb && echo "YOUR_SUDO_PASSWORD_HERE" | sudo -S dpkg -i -E ./aikido-php-firewall.x86_64.deb && echo "YOUR_SUDO_PASSWORD_HERE" | sudo -S service php8.4-fpm restart
1212
```
1313

1414
![Forge Commands](./forge-commands.png)

lib/agent/constants/constants.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package constants
22

33
const (
4-
Version = "1.5.1"
4+
Version = "1.5.2"
55
SocketPath = "/run/aikido-" + Version + "/aikido-agent.sock"
66
PidPath = "/run/aikido-" + Version + "/aikido-agent.pid"
77
ConfigUpdatedAtMethod = "GET"

lib/php-extension/Aikido.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,8 @@
44
ZEND_DECLARE_MODULE_GLOBALS(aikido)
55

66
PHP_MINIT_FUNCTION(aikido) {
7-
// For FrankenPHP: Set sapi_name but skip rest of LoadEnvironment during MINIT
8-
// Full environment will be loaded in RINIT when Caddyfile env vars are available
9-
if (sapi_module.name == std::string("frankenphp")) {
10-
AIKIDO_GLOBAL(sapi_name) = sapi_module.name;
11-
} else {
12-
// For other SAPIs: Load environment during MINIT as normal
13-
LoadEnvironment();
14-
}
7+
LoadSystemEnvironment();
8+
159
AIKIDO_GLOBAL(logger).Init();
1610

1711
AIKIDO_LOG_INFO("MINIT started!\n");

lib/php-extension/Environment.cpp

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,19 @@ std::string GetLaravelEnvVariable(const std::string& env_key) {
152152
*/
153153

154154
using EnvGetterFn = std::string(*)(const std::string&);
155-
EnvGetterFn envGetters[] = {
155+
156+
const std::vector<EnvGetterFn> completeEnvGetters = {
156157
&GetSystemEnvVariable,
157158
&GetFrankenEnvVariable,
158159
&GetPhpEnvVariable,
159160
&GetLaravelEnvVariable
160161
};
161162

162-
std::string GetEnvVariable(const std::string& env_key) {
163+
const std::vector<EnvGetterFn> systemEnvGetters = {
164+
&GetSystemEnvVariable,
165+
};
166+
167+
std::string GetEnvVariable(const std::vector<EnvGetterFn>& envGetters, const std::string& env_key) {
163168
for (EnvGetterFn envGetter : envGetters) {
164169
std::string env_value = envGetter(env_key);
165170
if (!env_value.empty()) {
@@ -169,8 +174,8 @@ std::string GetEnvVariable(const std::string& env_key) {
169174
return "";
170175
}
171176

172-
std::string GetEnvString(const std::string& env_key, const std::string default_value) {
173-
std::string env_value = GetEnvVariable(env_key);
177+
std::string GetEnvString(const std::vector<EnvGetterFn>& envGetters, const std::string& env_key, const std::string default_value) {
178+
std::string env_value = GetEnvVariable(envGetters, env_key);
174179
if (!env_value.empty()) {
175180
return env_value;
176181
}
@@ -185,12 +190,16 @@ bool GetBoolFromString(const std::string& env, bool default_value) {
185190
return default_value;
186191
}
187192

188-
bool GetEnvBool(const std::string& env_key, bool default_value) {
189-
return GetBoolFromString(GetEnvVariable(env_key), default_value);
193+
bool GetEnvBool(const std::vector<EnvGetterFn>& envGetters, const std::string& env_key, bool default_value) {
194+
return GetBoolFromString(GetEnvVariable(envGetters, env_key), default_value);
190195
}
191196

192-
unsigned int GetEnvNumber(const std::string& env_key, unsigned int default_value) {
193-
std::string env_value = GetEnvVariable(env_key.c_str());
197+
bool GetEnvBoolWithAllGetters(const std::string& env_key, bool default_value) {
198+
return GetBoolFromString(GetEnvVariable(completeEnvGetters, env_key), default_value);
199+
}
200+
201+
unsigned int GetEnvNumber(const std::vector<EnvGetterFn>& envGetters, const std::string& env_key, unsigned int default_value) {
202+
std::string env_value = GetEnvVariable(envGetters, env_key);
194203
if (!env_value.empty()) {
195204
try {
196205
unsigned int number = std::stoi(env_value);
@@ -203,26 +212,34 @@ unsigned int GetEnvNumber(const std::string& env_key, unsigned int default_value
203212
return default_value;
204213
}
205214

206-
void LoadEnvironment() {
215+
void LoadEnvironmentFromGetters(const std::vector<EnvGetterFn>& envGetters) {
207216
auto& logLevelStr = AIKIDO_GLOBAL(log_level_str);
208217
auto& logLevel = AIKIDO_GLOBAL(log_level);
209-
if (GetEnvBool("AIKIDO_DEBUG", false)) {
218+
if (GetEnvBool(envGetters, "AIKIDO_DEBUG", false)) {
210219
logLevelStr = "DEBUG";
211220
logLevel = AIKIDO_LOG_LEVEL_DEBUG;
212221
} else {
213-
logLevelStr = GetEnvString("AIKIDO_LOG_LEVEL", "WARN");
222+
logLevelStr = GetEnvString(envGetters, "AIKIDO_LOG_LEVEL", "WARN");
214223
logLevel = Log::ToLevel(logLevelStr);
215224
}
216225

217-
AIKIDO_GLOBAL(blocking) = GetEnvBool("AIKIDO_BLOCK", false) || GetEnvBool("AIKIDO_BLOCKING", false);;
218-
AIKIDO_GLOBAL(disable) = GetEnvBool("AIKIDO_DISABLE", false);
219-
AIKIDO_GLOBAL(collect_api_schema) = GetEnvBool("AIKIDO_FEATURE_COLLECT_API_SCHEMA", true);
220-
AIKIDO_GLOBAL(localhost_allowed_by_default) = GetEnvBool("AIKIDO_LOCALHOST_ALLOWED_BY_DEFAULT", true);
221-
AIKIDO_GLOBAL(trust_proxy) = GetEnvBool("AIKIDO_TRUST_PROXY", true);
222-
AIKIDO_GLOBAL(disk_logs) = GetEnvBool("AIKIDO_DISK_LOGS", false);
226+
AIKIDO_GLOBAL(blocking) = GetEnvBool(envGetters, "AIKIDO_BLOCK", false) || GetEnvBool(envGetters, "AIKIDO_BLOCKING", false);
227+
AIKIDO_GLOBAL(disable) = GetEnvBool(envGetters, "AIKIDO_DISABLE", false);
228+
AIKIDO_GLOBAL(collect_api_schema) = GetEnvBool(envGetters,"AIKIDO_FEATURE_COLLECT_API_SCHEMA", true);
229+
AIKIDO_GLOBAL(localhost_allowed_by_default) = GetEnvBool(envGetters, "AIKIDO_LOCALHOST_ALLOWED_BY_DEFAULT", true);
230+
AIKIDO_GLOBAL(trust_proxy) = GetEnvBool(envGetters, "AIKIDO_TRUST_PROXY", true);
231+
AIKIDO_GLOBAL(disk_logs) = GetEnvBool(envGetters, "AIKIDO_DISK_LOGS", false);
223232
AIKIDO_GLOBAL(sapi_name) = sapi_module.name;
224-
AIKIDO_GLOBAL(token) = GetEnvString("AIKIDO_TOKEN", "");
225-
AIKIDO_GLOBAL(endpoint) = GetEnvString("AIKIDO_ENDPOINT", "https://guard.aikido.dev/");
226-
AIKIDO_GLOBAL(config_endpoint) = GetEnvString("AIKIDO_REALTIME_ENDPOINT", "https://runtime.aikido.dev/");
227-
AIKIDO_GLOBAL(report_stats_interval_to_agent) = GetEnvNumber("AIKIDO_REPORT_STATS_INTERVAL", 100);
228-
}
233+
AIKIDO_GLOBAL(token) = GetEnvString(envGetters, "AIKIDO_TOKEN", "");
234+
AIKIDO_GLOBAL(endpoint) = GetEnvString(envGetters, "AIKIDO_ENDPOINT", "https://guard.aikido.dev/");
235+
AIKIDO_GLOBAL(config_endpoint) = GetEnvString(envGetters, "AIKIDO_REALTIME_ENDPOINT", "https://runtime.aikido.dev/");
236+
AIKIDO_GLOBAL(report_stats_interval_to_agent) = GetEnvNumber(envGetters, "AIKIDO_REPORT_STATS_INTERVAL", 100);
237+
}
238+
239+
void LoadEnvironment() {
240+
LoadEnvironmentFromGetters(completeEnvGetters);
241+
}
242+
243+
void LoadSystemEnvironment() {
244+
LoadEnvironmentFromGetters(systemEnvGetters);
245+
}

lib/php-extension/HandleFileCompilation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
#include "Includes.h"
22

33
zend_op_array* handle_file_compilation(zend_file_handle* file_handle, int type) {
4+
if(AIKIDO_GLOBAL(disable) == true) {
5+
return original_file_compilation_handler(file_handle, type);
6+
}
7+
48
auto& eventCacheStack = AIKIDO_GLOBAL(eventCacheStack);
59

610
// Create a new event context for file compilation

lib/php-extension/HookAst.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,17 @@ void insert_call_to_ast(zend_ast *ast) {
114114
}
115115

116116
void aikido_ast_process(zend_ast *ast) {
117+
auto& original_ast_process = AIKIDO_GLOBAL(originalAstProcess);
118+
119+
if(AIKIDO_GLOBAL(disable) == true) {
120+
if(original_ast_process){
121+
original_ast_process(ast);
122+
}
123+
return;
124+
}
125+
117126
insert_call_to_ast(ast);
118127

119-
auto& original_ast_process = AIKIDO_GLOBAL(originalAstProcess);
120128
if(original_ast_process){
121129
original_ast_process(ast);
122130
}

lib/php-extension/RequestProcessor.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,14 @@ bool RequestProcessorInstance::ReportStats() {
207207
bool RequestProcessorInstance::RequestInit() {
208208
std::string sapiName = sapi_module.name;
209209

210+
if (sapiName == "frankenphp") {
211+
if (GetEnvBoolWithAllGetters("FRANKENPHP_WORKER", false)) {
212+
AIKIDO_GLOBAL(isWorkerMode) = true;
213+
AIKIDO_LOG_INFO("FrankenPHP worker warm-up request detected, skipping RequestInit\n");
214+
return true;
215+
}
216+
}
217+
210218
if (sapiName == "apache2handler" || sapiName == "frankenphp") {
211219
// Apache-mod-php and FrankenPHP can serve multiple sites per process
212220
// We need to reload config each request to detect token changes
@@ -222,14 +230,6 @@ bool RequestProcessorInstance::RequestInit() {
222230
}
223231
}
224232

225-
if (sapiName == "frankenphp") {
226-
if (GetEnvBool("FRANKENPHP_WORKER", false)) {
227-
AIKIDO_GLOBAL(isWorkerMode) = true;
228-
AIKIDO_LOG_INFO("FrankenPHP worker warm-up request detected, skipping RequestInit\n");
229-
return true;
230-
}
231-
}
232-
233233
// Initialize the request processor only once(lazy) during RINIT because php-fpm forks the main process
234234
// for workers and we need to load the library after the worker process is forked because
235235
// the request processor is a go library that brings in the Go runtime, which (once initialized)

0 commit comments

Comments
 (0)