Compare commits

...

10 Commits

Author SHA1 Message Date
Ned Wright
110f0c8bd2 Aug 20th update 2024-08-21 08:42:14 +00:00
WrightNed
ca31aac08a Merge pull request #174 from openappsec/orianelou-patch-6
Update docker-compose.yaml
2024-08-20 15:17:02 +03:00
orianelou
161b6dd180 Update docker-compose.yaml 2024-08-20 14:50:01 +03:00
WrightNed
84327e0b19 Merge pull request #170 from openappsec/orianelou-patch-4
Create docker-compose.yaml
2024-08-05 13:12:40 +03:00
orianelou
b9723ba6ce Create docker-compose.yaml
added compose for docker SWAG
2024-08-05 12:06:37 +03:00
WrightNed
00e183b8c6 Merge pull request #169 from openappsec/Jul_31_2024-Dev
Jul 31st update
2024-08-01 18:10:44 +03:00
WrightNed
e859c167ed Merge pull request #167 from openappsec/orianelou-crds
Orianelou crds
2024-08-01 18:10:11 +03:00
orianelou
805e958cb9 Create open-appsec-crd-latest.yaml 2024-07-25 12:06:59 +03:00
orianelou
5bcd7cfcf1 Create open-appsec-crd-v1beta2.yaml 2024-07-25 12:05:57 +03:00
orianelou
ae6f2faeec Create open-appsec-crd-v1beta1.yaml 2024-07-25 12:04:22 +03:00
17 changed files with 3368 additions and 15 deletions

View File

@@ -89,7 +89,9 @@ private:
bool matchAttributesRegEx(const std::set<std::string> &values,
std::set<std::string> &matched_override_keywords) const;
bool matchAttributesString(const std::set<std::string> &values) const;
bool matchAttributesIp(const std::set<std::string> &values) const;
bool isRegEx() const;
bool isIP() const;
MatchType type;
Operators operator_type;

View File

@@ -385,8 +385,29 @@ Layer7AccessControl::Impl::init()
i_intelligence = Singleton::Consume<I_Intelligence_IS_V2>::by<Layer7AccessControl>();
i_mainloop = Singleton::Consume<I_MainLoop>::by<Layer7AccessControl>();
chrono::minutes expiration(
getProfileAgentSettingWithDefault<uint>(60u, "layer7AccessControl.crowdsec.cacheExpiration")
int cache_expiration_in_seconds = 30;
string cache_expiration_env = getenv("CROWDSEC_CACHE_EXPIRATION") ? getenv("CROWDSEC_CACHE_EXPIRATION") : "";
if (!cache_expiration_env.empty()) {
if (
all_of(cache_expiration_env.begin(), cache_expiration_env.end(), ::isdigit)
&& stoi(cache_expiration_env) > 0
) {
cache_expiration_in_seconds = stoi(cache_expiration_env);
dbgInfo(D_L7_ACCESS_CONTROL)
<< "Successfully read cache expiration value from env: "
<< cache_expiration_env;
} else {
dbgWarning(D_L7_ACCESS_CONTROL)
<< "An invalid cache expiration value was provided in env: "
<< cache_expiration_env;
}
}
chrono::seconds expiration(
getProfileAgentSettingWithDefault<uint>(
cache_expiration_in_seconds,
"layer7AccessControl.crowdsec.cacheExpiration"
)
);
ip_reputation_cache.startExpiration(

View File

@@ -117,6 +117,7 @@ public:
OrchestrationStatusResult getOrchestrationStatusResult() const;
std::string parseDescription() const;
std::string getDescriptionWithoutErrors() const;
private:
UpdatesProcessResult result;

View File

@@ -556,7 +556,7 @@ TEST_F(OrchestrationStatusTest, checkErrorByRaiseEvent)
"Time",
"Online upgrades",
fog_address,
"Failed. Reason: Registration failed. Error: " + registar_error,
"Failed. Reason: Registration failed.",
"Failed. Reason: " + manifest_error
),
result

View File

@@ -473,7 +473,11 @@ public:
void
upon(const UpdatesProcessEvent &event) override
{
setFieldStatus(event.getStatusFieldType(), event.getOrchestrationStatusResult(), event.parseDescription());
setFieldStatus(
event.getStatusFieldType(),
event.getOrchestrationStatusResult(),
event.getDescriptionWithoutErrors()
);
}
private:

View File

@@ -122,3 +122,62 @@ UpdatesProcessEvent::parseDescription() const
}
return err.str();
}
string
UpdatesProcessEvent::getDescriptionWithoutErrors() const
{
stringstream err;
if (description.empty() || result == UpdatesProcessResult::SUCCESS) return "";
switch (reason) {
case UpdatesFailureReason::CHECK_UPDATE: {
err << description;
break;
}
case UpdatesFailureReason::REGISTRATION: {
err << "Registration failed.";
break;
}
case UpdatesFailureReason::GET_UPDATE_REQUEST: {
err << "Failed to get update request.";
break;
}
case UpdatesFailureReason::DOWNLOAD_FILE : {
err << "Failed to download the file " << detail;
break;
}
case UpdatesFailureReason::HANDLE_FILE : {
err << "Failed to handle the file " << detail;
break;
}
case UpdatesFailureReason::INSTALLATION_QUEUE : {
err << "Installation queue creation failed.";
break;
}
case UpdatesFailureReason::INSTALL_PACKAGE : {
err << "Failed to install the package " << detail;
break;
}
case UpdatesFailureReason::CHECKSUM_UNMATCHED : {
err << "Checksums do not match for the file: " << detail;
break;
}
case UpdatesFailureReason::POLICY_CONFIGURATION : {
err << "Failed to configure policy version: " << detail;
break;
}
case UpdatesFailureReason::POLICY_FOG_CONFIGURATION : {
err << "Failed to configure the fog address: " << detail;
break;
}
case UpdatesFailureReason::ORCHESTRATION_SELF_UPDATE : {
err << description;
break;
}
case UpdatesFailureReason::NONE : {
err << description;
break;
}
}
return err.str();
}

View File

@@ -57,7 +57,6 @@ private:
std::vector<std::string> filesPathsList;
};
class I_Serializable {
public:
virtual void serialize(std::ostream& stream) = 0;

View File

@@ -397,7 +397,7 @@ SerializeToLocalAndRemoteSyncBase::SerializeToLocalAndRemoteSyncBase(
const string &owner
) :
SerializeToFileBase(filePath),
m_remotePath(remotePath),
m_remotePath(replaceAllCopy(remotePath, "//", "/")),
m_interval(0),
m_owner(owner),
m_pMainLoop(nullptr),
@@ -407,7 +407,7 @@ SerializeToLocalAndRemoteSyncBase::SerializeToLocalAndRemoteSyncBase(
m_windowsCount(0),
m_intervalsCounter(0),
m_remoteSyncEnabled(true),
m_assetId(assetId),
m_assetId(replaceAllCopy(assetId, "/", "")),
m_isAssetIdUuid(Waap::Util::isUuid(assetId)),
m_shared_storage_host(genError("not set")),
m_learning_host(genError("not set"))
@@ -439,7 +439,7 @@ SerializeToLocalAndRemoteSyncBase::SerializeToLocalAndRemoteSyncBase(
}
if (remotePath != "") {
// remote path is /<tenantId>/<assetId>/<type>
auto parts = split(remotePath, '/');
auto parts = split(m_remotePath, '/');
if (parts.size() > 2) {
size_t offset = 0;
if (parts[0].empty()) {
@@ -656,8 +656,7 @@ void SerializeToLocalAndRemoteSyncBase::syncWorker()
OrchestrationMode mode = Singleton::exists<I_AgentDetails>() ?
Singleton::Consume<I_AgentDetails>::by<WaapComponent>()->getOrchestrationMode() : OrchestrationMode::ONLINE;
if (mode == OrchestrationMode::OFFLINE || !m_remoteSyncEnabled || isBase() ||
(mode == OrchestrationMode::ONLINE && !m_isAssetIdUuid) || !postData()) {
if (mode == OrchestrationMode::OFFLINE || !m_remoteSyncEnabled || isBase() || !postData()) {
dbgDebug(D_WAAP_CONFIDENCE_CALCULATOR)
<< "Did not synchronize the data. for asset: "
<< m_assetId

View File

@@ -37,7 +37,14 @@ WaapTelemetryBase::sendLog(const LogRest &metric_client_rest) const
if (mode == OrchestrationMode::ONLINE) {
return;
}
auto svc_host = getConfigurationWithDefault(default_host, "Logging", "K8sSvc Log host");
const char* host_env_var = getenv("TUNING_HOST");
string host;
if (host_env_var != nullptr && strlen(host_env_var) > 0) {
host = string(host_env_var);
} else {
host = default_host;
}
auto svc_host = getConfigurationWithDefault(host, "Logging", "Container Log host");
string fog_metric_uri = getConfigurationWithDefault<string>("/api/v1/agents/events", "metric", "fogMetricUri");
MessageMetadata req_md(svc_host, 80);
req_md.insertHeader(

View File

@@ -15,6 +15,7 @@
#include "i_mainloop.h"
#include "i_serialize.h"
#include "waap.h"
#include "Waf2Util.h"
using namespace std;
@@ -25,7 +26,7 @@ USE_DEBUG_FLAG(D_WAAP);
TuningDecision::TuningDecision(const string& remotePath)
:
m_remotePath(remotePath + "/tuning"),
m_remotePath(replaceAllCopy(remotePath + "/tuning", "//", "/")),
m_baseUri()
{
if (remotePath == "")

View File

@@ -733,6 +733,12 @@ inline void replaceAll(std::string& str, const std::string& from, const std::str
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}
}
inline std::string replaceAllCopy(std::string str, const std::string& from, const std::string& to) {
replaceAll(str, from, to);
return str;
}
inline void alignBase64Chunk (std::string &chunk)
{
size_t len = chunk.length() % 4;

View File

@@ -299,7 +299,16 @@ MatchQuery::matchAttributes(
{
auto &type = condition_type;
bool negate = type == MatchQuery::Conditions::NotEquals || type == MatchQuery::Conditions::NotIn;
bool match = isRegEx() ? matchAttributesRegEx(values, matched_override_keywords) : matchAttributesString(values);
bool match = false;
if (isIP()) {
match = matchAttributesIp(values);
} else if (isRegEx()) {
match = matchAttributesRegEx(values, matched_override_keywords);
} else {
match = matchAttributesString(values);
}
return negate ? !match : match;
}
@@ -340,8 +349,26 @@ MatchQuery::matchAttributesString(const set<string> &values) const
return false;
}
bool
MatchQuery::matchAttributesIp(const set<string> &values) const
{
for (const IPRange &rule_ip_range : ip_addr_value) {
for (const string &requested_value : values) {
IpAddress ip_addr = IPUtilities::createIpFromString(requested_value);
if (IPUtilities::isIpAddrInRange(rule_ip_range, ip_addr)) return true;
}
}
return false;
}
bool
MatchQuery::isRegEx() const
{
return key != "protectionName";
}
bool
MatchQuery::isIP() const
{
return key == "sourceIP" || key == "destinationIP";
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,525 @@
Enter file contents hereapiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata :
name : customresponses.openappsec.io
spec:
group: openappsec.io
versions:
- name: v1beta1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
mode:
type: string
enum:
- block-page
#- redirect
- response-code-only
message-title:
type: string
message-body:
type: string
http-response-code:
type: integer
minimum: 100
maximum: 599
scope: Cluster
names:
plural: customresponses
singular: customresponse
kind: CustomResponse
shortNames:
- customresponse
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: exceptions.openappsec.io
spec:
group: openappsec.io
versions:
- name: v1beta1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: array
items:
type: object
required:
- action
properties:
action:
type: string
enum:
- skip
- accept
- drop
- suppressLog
sourceIp:
type: array
items:
type: string
url:
type: array
items:
type: string
sourceIdentifier:
type: array
items:
type: string
protectionName:
type: array
items:
type: string
paramValue:
type: array
items:
type: string
paramName:
type: array
items:
type: string
hostName:
type: array
items:
type: string
countryCode:
type: array
items:
type: string
countryName:
type: array
items:
type: string
comment:
type: string
scope: Cluster
names:
plural: exceptions
singular: exception
kind: Exception
shortNames:
- exception
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata :
name : logtriggers.openappsec.io
spec:
group: openappsec.io
versions:
- name: v1beta1
# Each version can be enabled/disabled by Served flag.
served: true
# One and only one version must be marked as the storage version.
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
access-control-logging:
type: object
properties:
allow-events:
type: boolean
drop-events:
type: boolean
appsec-logging:
type: object
properties:
detect-events:
type: boolean
prevent-events:
type: boolean
all-web-requests:
type: boolean
additional-suspicious-events-logging:
type: object
properties:
enabled:
type: boolean
minimum-severity:
type: string
enum:
- high
- critical
response-body:
type: boolean
response-code:
type: boolean
extended-logging:
type: object
properties:
url-path:
type: boolean
url-query:
type: boolean
http-headers:
type: boolean
request-body:
type: boolean
log-destination:
type: object
properties:
cloud:
type: boolean
syslog-service: #change to object array
type: array
items:
type: object
properties:
address:
type: string
port:
type: integer
file:
type: string
stdout:
type: object
properties:
format:
type: string
enum:
- json
- json-formatted
cef-service:
type: array
items:
type: object
properties:
address:
type: string
port:
type: integer
proto:
type: string
enum:
- tcp
- udp
scope: Cluster
names:
plural: logtriggers
singular: logtrigger
kind: LogTrigger
shortNames:
- logtrigger
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata :
name : policies.openappsec.io
spec:
group: openappsec.io
versions:
- name: v1beta1
# Each version can be enabled/disabled by Served flag.
served: true
# One and only one version must be marked as the storage version.
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
default:
type: object
properties:
mode:
type: string
enum:
- prevent-learn
- detect-learn
- prevent
- detect
- inactive
practices:
type: array
items:
type: string
triggers:
type: array
items:
type: string
custom-response:
type: string
source-identifiers:
type: string
trusted-sources:
type: string
exceptions:
type: array
items:
type: string
specific-rules:
type: array
items:
type: object
properties:
host:
type: string
mode:
type: string
enum:
- prevent-learn
- detect-learn
- prevent
- detect
- inactive
practices:
type: array
items:
type: string
triggers:
type: array
items:
type: string
custom-response:
type: string
source-identifiers:
type: string
trusted-sources:
type: string
exceptions:
type: array
items:
type: string
scope: Cluster
names:
plural: policies
singular: policy
kind: Policy
shortNames:
- policy
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata :
name : practices.openappsec.io
spec:
group: openappsec.io
versions:
- name: v1beta1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
web-attacks:
type: object
properties:
override-mode:
type: string
enum:
- prevent-learn
- detect-learn
- prevent
- detect
- inactive
minimum-confidence:
type: string
enum:
- medium
- high
- critical
max-url-size-bytes:
type: integer
max-object-depth:
type: integer
max-body-size-kb:
type: integer
max-header-size-bytes:
type: integer
protections:
type: object
properties:
csrf-enabled:
type: string
enum:
- prevent-learn
- detect-learn
- prevent
- detect
- inactive
error-disclosure-enabled:
type: string
enum:
- prevent-learn
- detect-learn
- prevent
- detect
- inactive
open-redirect-enabled:
type: string
enum:
- prevent-learn
- detect-learn
- prevent
- detect
- inactive
non-valid-http-methods:
type: boolean
anti-bot:
type: object
properties:
override-mode:
type: string
enum:
- prevent-learn
- detect-learn
- prevent
- detect
- inactive
injected-URIs:
type: array
items:
type: object
properties:
uri:
type: string
validated-URIs:
type: array
items:
type: object
properties:
uri:
type: string
snort-signatures:
type: object
properties:
override-mode:
type: string
enum:
- prevent-learn
- detect-learn
- prevent
- detect
- inactive
configmap:
type: array
items:
type: string
openapi-schema-validation:
type: object
properties:
override-mode:
type: string
enum:
- prevent-learn
- detect-learn
- prevent
- detect
- inactive
configmap:
type: array
items:
type: string
scope: Cluster
names:
plural: practices
singular: practice
kind: Practice
shortNames:
- practice
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata :
name : sourcesidentifiers.openappsec.io
spec:
group: openappsec.io
versions:
- name: v1beta1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: array
items:
type: object
properties:
sourceIdentifier:
type: string
enum:
- headerkey
- JWTKey
- cookie
- sourceip
- x-forwarded-for
value:
type: array
items:
type: string
scope: Cluster
names:
plural: sourcesidentifiers
singular: sourcesidentifier
kind: SourcesIdentifier
shortNames:
- sourcesidentifier
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata :
name : trustedsources.openappsec.io
spec:
group: openappsec.io
versions:
- name: v1beta1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
minNumOfSources:
type: integer
sourcesIdentifiers:
type: array
items:
type: string
scope: Cluster
names:
plural: trustedsources
singular: trustedsource
kind: TrustedSource
shortNames:
- trustedsource

File diff suppressed because it is too large Load Diff

View File

@@ -35,7 +35,14 @@ ContainerSvcStream::~ContainerSvcStream()
void
ContainerSvcStream::sendLog(const Report &log)
{
auto svc_host = getConfigurationWithDefault(default_host, "Logging", "Container Log host");
const char* host_env_var = getenv("TUNING_HOST");
string host;
if (host_env_var != nullptr && strlen(host_env_var) > 0) {
host = string(host_env_var);
} else {
host = default_host;
}
auto svc_host = getConfigurationWithDefault(host, "Logging", "Container Log host");
auto svc_log_uri = getConfigurationWithDefault(default_log_uri, "Logging", "Container Log URI");
LogRest rest(log);
@@ -66,7 +73,14 @@ ContainerSvcStream::sendLog(const LogBulkRest &logs, bool persistence_only)
return;
}
auto svc_host = getConfigurationWithDefault(default_host, "Logging", "Container Log host");
const char* host_env_var = getenv("TUNING_HOST");
string host;
if (host_env_var != nullptr && strlen(host_env_var) > 0) {
host = string(host_env_var);
} else {
host = default_host;
}
auto svc_host = getConfigurationWithDefault(host, "Logging", "Container Log host");
auto svc_log_uri = getConfigurationWithDefault(default_bulk_uri, "Logging", "Container Bulk Log URI");
MessageMetadata rest_req_md(svc_host, 80);

View File

@@ -0,0 +1,46 @@
services:
swag-attachment:
image: ghcr.io/openappsec/swag-attachment:latest
ipc: service:appsec-agent
restart: unless-stopped
container_name: swag-attachment
cap_add:
- NET_ADMIN
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- URL=yourdomain.url # replace yourdomain.url with your own domain
# make sure your domain's public IP resolves to
# the docker host for Let's Encrypt cert generation to succeed
- VALIDATION=http
# see https://docs.linuxserver.io/images/docker-swag/ for
# more cert generation/validation options
- STAGING=true # switch to 'false' after successful testing
volumes:
- ./swag-config:/config
ports:
- 443:443
- 80:80 #optional
appsec-agent:
container_name: appsec-agent
image: ghcr.io/openappsec/agent:latest
ipc: shareable
restart: unless-stopped
environment:
- user_email=user@email.com # adjust with your own email
- registered_server='SWAG'
# if autoPolicyLoad is set to true, open-appsec will apply
# changes in local_policy.yaml automatically
- autoPolicyLoad=true
# To connect to open-appsec central management WebUI
## create your WebUI profile at https://my.openappsec.io,
## enforce policy, copy the profile token from WebUI and add it below
- AGENT_TOKEN=
volumes:
- ./appsec-config:/etc/cp/conf
- ./appsec-data:/etc/cp/data
- ./appsec-logs:/var/log/nano_agent
- ./appsec-localconfig:/ext/appsec
command: /cp-nano-agent