Compare commits

...

19 Commits
main ... 25u

Author SHA1 Message Date
e2352f203b
Adding enforcement exit code 2024-01-18 12:04:49 -06:00
d7db9b5b9f
Adding commentary header 2024-01-18 12:02:49 -06:00
3845470bb7
Extending for WAPs 2024-01-16 16:34:30 -06:00
15b1d9dcc0
Adding routing page 2024-01-16 14:56:43 -06:00
6d52c6771f
Removing ambiguous character 2024-01-15 11:13:41 -06:00
87adb4e14d
25U subnetting app 2024-01-12 20:03:08 -06:00
f9a3bd789b
Removing duplicate resource 2024-01-12 16:17:55 -06:00
15dd844093
Correcting abandoned rename 2024-01-12 16:10:40 -06:00
43d7375dae
Updating AniNIX/Scratch for naming & persistence warning 2024-01-12 15:34:41 -06:00
cd3210c5fb
Adding minor webapps to WebServer tracking 2024-01-12 13:06:58 -06:00
221ce69a80
Catching up wolfpack to reenable 2024-01-12 13:06:19 -06:00
1ca0272031
Adding ucode & UPS definitions to IAC 2023-12-21 12:58:32 -06:00
e244895552
Finalizing Cyberbrain role 2023-12-19 16:20:58 -06:00
cea66f285a
Finishing rename from Core to Yggdrasil 2023-12-19 16:16:35 -06:00
50167c0f03
Virtualizing Core host as Yggdrasil VM 2023-12-07 13:28:54 -06:00
7b98c953b1
Merging out nginx conversion 2023-11-30 02:48:50 -06:00
528af8b0f5
Fixing PKGBUILD dependencies 2023-11-16 12:58:52 -06:00
9b317d1677
Dropping Stripe as a payment method (will replace with Venmo/USDCoin address) & Google Analytics for AniNIX/Sharingan -- some updates for CSP in line with https://observatory.mozilla.org/analyze/aninix.net 2023-11-16 12:50:26 -06:00
5fa67890c2
Moving from openresty to nginx+modsec for HTTP/2 Rapid Reset reasons 2023-11-09 13:03:06 -06:00
75 changed files with 1586 additions and 408 deletions

1
.gitignore vendored
View File

@ -7,6 +7,7 @@ roles/ShadowArch/files/mirrorlist
roles/Sharingan/files/monit/checks/availability
roles/Foundation/files/custom/public/img/**
venv/**
wiki/**
**/pkg/**
**/src/**
**pkg.tar.zst

View File

@ -4,10 +4,10 @@ pkgrel=1
pkgrel() {
git log "$(git describe --tag --abbrev=0)"..HEAD | grep -c commit
}
epoch=
epoch="$(git log | grep -c commit)"
pkgdesc="$(head -n 1 README.md)"
arch=("x86_64")
url="https://aninix.net/foundation/${pkgname}"
url="$(git config remote.origin.url | sed 's/.git$//')"
license=('custom')
groups=()
depends=('bash>=4.4' 'python>=3.11' 'ansible>=8.3' 'tmux' 'openssh')

View File

@ -1,6 +1,4 @@
This project will discover and provide inventory intelligence to Sora, Shadowfeed, Geth, and Sharingan.
*Note*: This project is in progress -- former Makefiles from [ConfigPackages](/AniNIX/ConfigPackages) are being upgraded into Ansible playbooks here.
This project is our Infrastructure-as-Code solution, detailing the deployment & some repeatable operational tasks of the AniNIX.
# Etymology
@ -30,14 +28,22 @@ We've also added two scripts in `./bin` to make your life easier:
Happy hacking!
## Exceptions
# Etymology
Some services, such as AniNIX/Sharingan and AniNIX/Geth, store their configuration in internal datastructures and databases such that we cannot easily export our build for others to use. We will document what we have done for each of these as best we can in the README.md files for others to replicate. Backups of these services into AniNIX/Aether are therefore dumps of these databases and not available to share.
The [Ubiqtorate](https://starwars.fandom.com/wiki/Ubiqtorate/Legends) was a far-reaching security orchestration entity within Palpatine's Empire. It was mean to collect and act on intelligence to improve the security posture of the regime. We use this project similarly -- Ubiqtorate is the Infrastructure-as-Code behind the throne, making changes and ensuring services stay in line.
# Relevant Files and Software
This project is mostly built on [Ansible](https://docs.ansible.com/). You will need to understand inventories, playbooks, and vaults at the minimum.
# Available Clients
This service is a management tool -- its files get used by the Ansible toolset. There are no clients to connect directly to this service, as we have chosen a serverless approach.
None -- this project is used to describe actions for other services to take.
# Equivalents or Competition
This service is our elected Infrastructure-as-Code solution -- many professional tools like Ansible Tower, Terraform, etc. do the same thing. Some apps ship OVA's, or prebuilt images, of their software. Docker registries also serve as similar way to document the means by which services are built.
Similar tools include Puppet, chef, salty, Ansible Tower, Terraform, etc. We have chosen to go the raw Ansible route, so that we don't have to maintain the build infrastructure separately and to make our responses more agile.
# Exceptions
Some services, such as AniNIX/Sharingan and AniNIX/Geth, store their configuration in internal datastructures and databases such that we cannot easily export our build for others to use. We will document what we have done for each of these as best we can in the README.md files for others to replicate. Backups of these services into AniNIX/Aether are therefore dumps of these databases and not available to share.

View File

@ -13,7 +13,7 @@ import shutil
import sys
import yaml
filepath="roles/Node/files/vm-definitions/"
filepath="../roles/Node/files/vm-definitions/"
def WriteVMFile(content,hosttype,hostclass):
### Create the service files for the hosts
@ -84,7 +84,7 @@ def GenerateFiles(file):
# Add service files for each host
WriteVMFile(content,'managed','virtual')
WriteVMFile(content,'unmanaged','ovas',
WriteVMFile(content,'unmanaged','ovas')
WriteVMFile(content,'unmanaged','test_ovas')
if __name__ == '__main__':

View File

@ -44,39 +44,54 @@ all:
ip: 10.0.1.2
mac: B8:27:EB:B6:AA:0C
static: true
Core:
ipinterface: enp1s0f0
ip: 10.0.1.3
mac: 00:25:90:0d:6e:86
static: true
sslidentity: aninix.net-0001
secdetection: true
iptv_location: "Milwaukee|Madison"
aether_source: true
Node0:
ipinterface: enp1s0f0
ip: 10.0.1.4
mac: DE:8B:9E:19:55:1D
tap: true
Node1:
ipinterface: enp1s0f0
ipinterface: enp1s0
ip: 10.0.1.5
mac: B0:41:6F:0D:47:E1
mac: FA:EC:43:87:4D:2D
tap: true
ups: 'aps'
Node2:
ipinterface: enp1s0f0
ipinterface: enp1s0
ip: 10.0.1.7
mac: B0:41:6F:0D:41:D1
mac: 56:02:ef:2c:1f:7c
tap: true
ups: 'cyberpower'
Node3:
ipinterface: enp1s0f0
ipinterface: enp1s0
ip: 10.0.1.8
mac: B0:41:6F:0D:51:0E
mac: B2:C6:2C:02:B2:6E
tap: true
Nodelet0:
ipinterface: eth0
ip: 10.0.1.9
mac: b8:27:eb:9a:73:dd
static: true
k3s_primary: true
Nodelet1:
ipinterface: eth0
ip: 10.0.1.10
mac: E4:5F:01:01:FF:9C
static: true
Nodelet2:
ipinterface: eth0
ip: 10.0.1.11
mac: E4:5F:01:01:FF:D5
static: true
Nodelet3:
ipinterface: eth0
ip: 10.0.1.12
mac: E4:5F:01:01:FF:96
static: true
Nodelet4:
ipinterface: eth0
ip: 10.0.1.13
mac: E4:5F:01:01:FF:E4
static: true
virtual: # 10.0.1.16/28
vars:
hosts:
Sharingan:
node: Node2
ip: 10.0.1.16
ipinterface: ens3
mac: 00:15:5D:01:02:10
@ -87,19 +102,23 @@ all:
uefi: true
siem: true
disks:
- '-drive format=raw,index=0,media=disk,file=/dev/sdb'
- '-drive format=raw,index=0,media=disk,file=/dev/sdc'
# On hold because of https://aninix.net/DarkFeather/MSN0/issues/6
holdpkg: "elasticsearch graylog mongodb44-bin mongodb-tools-bin"
DarkNet:
node: Node2
ipinterface: ens3
ip: 10.0.1.17
mac: 00:15:5D:01:02:05
cores: 2
memory: 2
cores: 4
memory: 4
vnc: 9
bridge: br0
disks:
- '-drive format=raw,index=0,media=disk,file=/dev/sdd'
- '-drive format=raw,index=0,media=disk,file=/dev/sdb'
wolfpack_config: 'gitea@foundation.aninix.net:DarkFeather/WolfPack-Config.git'
Maat:
node: Node2
ip: 10.0.1.18
ipinterface: ens3
mac: 00:15:5d:01:02:07
@ -108,8 +127,26 @@ all:
bridge: br0
vnc: 7
disks:
- '-drive format=qcow2,l2-cache-size=8M,file=/srv/maat/vm/Maat.qcow2'
- '-drive format=qcow2,l2-cache-size=8M,file=/mnt/cage2/vm/Maat.qcow2'
Yggdrasil:
node: Node1
ipinterface: enp1s0f0
ip: 10.0.1.3
mac: 00:25:90:0d:6e:86
static: true
sslidentity: aninix.net-0001
secdetection: true
iptv_location: "Milwaukee|Madison"
aether_source: true
cores: 8
memory: 16
bridge: br0
vnc: 1
disks:
- '-drive format=raw,index=0,media=disk,file=/dev/sda'
- '-drive format=raw,index=0,media=disk,file=/dev/sdb'
- '-drive format=raw,index=0,media=disk,file=/dev/sdc'
- '-drive format=raw,index=0,media=disk,file=/dev/sdd'
geth_hubs: # 10.0.1.32/28
vars:
motion_enabled: yes
@ -136,6 +173,7 @@ all:
ovas: # 10.0.1.48/28
hosts:
Geth:
node: Node2
ip: 10.0.1.49
mac: DE:8B:9E:19:55:1E
cores: 2
@ -144,10 +182,11 @@ all:
bridge: br0
uefi: true
disks:
- '-drive format=qcow2,l2-cache-size=8M,file=/srv/maat/vm/hassos_ova-5.13.qcow2'
- '-drive format=qcow2,l2-cache-size=8M,file=/mnt/cage2/vm/hassos_ova-5.13.qcow2'
test_ovas: # 10.0.1.48/28
hosts:
TDS-Jump:
node: Node2
ip: 10.0.1.48
mac: 00:15:5d:01:02:08
cores: 2
@ -155,7 +194,7 @@ all:
vnc: 4
bridge: br0
disks:
- '-drive format=qcow2,l2-cache-size=8M,file=/srv/maat/vm/TDSJump.qcow2'
- '-drive format=qcow2,l2-cache-size=8M,file=/mnt/cage2/vm/TDSJump.qcow2'
DedNet:
ip: 10.0.1.50
mac: 00:15:5d:01:02:09
@ -164,7 +203,7 @@ all:
vnc: 3
bridge: br0
disks:
- '-drive format=qcow2,l2-cache-size=8M,file=/srv/maat/vm/DedNet.qcow2'
- '-drive format=qcow2,l2-cache-size=8M,file=/mnt/cage2/vm/DedNet.qcow2'
- '-cdrom /srv/maat/iso/kali-linux.iso -boot order=d'
Aether:
ip: 10.0.1.51
@ -185,7 +224,7 @@ all:
bridge: br0
vnc: 10
disks:
- '-drive format=qcow2,l2-cache-size=8M,file=/srv/maat/vm/test1.qcow2'
- '-drive format=qcow2,l2-cache-size=8M,file=/mnt/cage2/vm/test1.qcow2'
test2:
ip: 10.0.1.53
ipinterface: ens3
@ -195,7 +234,7 @@ all:
bridge: br0
vnc: 11
disks:
- '-drive format=qcow2,l2-cache-size=8M,file=/srv/maat/vm/test2.qcow2'
- '-drive format=qcow2,l2-cache-size=8M,file=/mnt/cage2/vm/test2.qcow2'
test3:
ip: 10.0.1.54
ipinterface: ens3
@ -205,7 +244,7 @@ all:
bridge: br0
vnc: 12
disks:
- '-drive format=qcow2,l2-cache-size=8M,file=/srv/maat/vm/test3.qcow2'
- '-drive format=qcow2,l2-cache-size=8M,file=/mnt/cage2/vm/test3.qcow2'
# appliances are monitored -- adhoc_appliances are convenience only and not monitored.
appliances:
hosts: # 10.0.1.64/27
@ -218,12 +257,12 @@ all:
Geth-Eyes:
ip: 10.0.1.68
mac: 9C:A3:AA:33:A3:99
"Core-Console":
ip: 10.0.1.74
mac: 00:25:90:0D:82:5B
"Node0-Console":
ip: 10.0.1.75
mac: 00:25:90:3E:C6:8C
# "Core-Console":
# ip: 10.0.1.74
# mac: 00:25:90:0D:82:5B
# "Node0-Console":
# ip: 10.0.1.75
# mac: 00:25:90:3E:C6:8C
adhoc_appliances:
hosts: # 10.0.1.64/27
DarkFeather:
@ -247,7 +286,7 @@ all:
Tachikoma:
ip: 10.0.1.72
mac: 90:0f:0c:1a:d3:23
Dedsec:
DedSec:
ip: 10.0.1.73
mac: 34:F6:4B:36:12:8F
# dhcp build space: 10.0.1.224/27
@ -262,6 +301,7 @@ all:
Charon:
ip: 10.0.2.4
mac: 64:52:99:14:28:2B
Skitarii-1:
# CanoptekAleph: physical, no network
CanoptekBek:
ip: 10.0.2.5
mac: 40:9F:38:95:06:34

View File

@ -34,7 +34,7 @@
- SSH
- Sharingan
- hosts: Core
- hosts: Yggdrasil
order: sorted
serial: "{{ threads | default('16') }}"
gather_facts: true
@ -46,6 +46,9 @@
- SSL
- WebServer
- IRC
- WolfPack
- Foundation
- Yggrasil
- hosts: geth_hubs
order: sorted
@ -57,7 +60,7 @@
roles:
- Geth-Hub
- hosts: Node0
- hosts: Node1,Node2,Node3
order: sorted
serial: "{{ threads | default('16') }}"
gather_facts: true
@ -77,3 +80,4 @@
- "{{ lookup('env', 'ANSIBLE_VAULT_FILE') }}"
roles:
- DarkNet
- WolfPack

View File

@ -0,0 +1,12 @@
#!/bin/bash
# Webserver apps directory should be short -- apps that fail this category should become their own.
retcode=0
for file in `find roles/WebServer/files/apps -type f`; do
if [[ $(wc -l "$file" | awk '{ print $1; }') -gt 10 ]]; then
echo "$file" is too long to be deployed as a mini-app under the WebServer role.
retcode=1
fi
done
exit $retcode

View File

@ -1,12 +1,16 @@
Cyberbrain is a way to ensure that so long as a person is connected to the Internet and authorized, they're able to connect to, use, and control the AniNIX. It's a web-based shell emulator for connecting to the system. It can serve as an alternative to using the [Terminal & SSH add-on](https://www.home-assistant.io/common-tasks/supervised/#installing-and-using-the-ssh-add-on-requires-enabling-advanced-mode-for-the-ha-user) for [AniNIX/Geth](../Geth/) in cases where a separate security posture is needed for each.
Cyberbrain is a way to ensure that so long as a person is connected to the Internet and authorized, they're able to connect to, use, and control the AniNIX.
**Warning**: This is a fallback measure -- browsers are still inherently less secure than hard clients like [Git Bash](https://git-scm.com/download/win) or [OpenSSH](https://www.openssh.com/portable.html).
It can serve as an alternative to using the [Terminal & SSH add-on](https://www.home-assistant.io/common-tasks/supervised/#installing-and-using-the-ssh-add-on-requires-enabling-advanced-mode-for-the-ha-user) for [AniNIX/Geth](../Geth/) in cases where a separate security posture is needed for each.
# Etymology
A [cyberbrain](https://ghostintheshell.fandom.com/wiki/Cyberbrain) is a concept from the series *Ghost in the Shell*. It's the integration of a normal brain with electronic, usually networked components. Similarly, this app serves as a core bridge between the shell environment of the AniNIX and any authorized user.
# Relevant Files and Software
This service uses a file, [/etc/conf.d/webssh](file:///etc/conf.d/webssh), to control the service. Additionally, there's a password file [/opt/openresty/nginx/passwords/cyberbrain.htpasswd](file:///opt/openresty/nginx/passwords/cyberbrain.htpasswd) that controls an initial authentication to the webserver socket.
This service is deployed as a Docker image from [FileStash](https://www.filestash.app/docs/install-and-upgrade/). This image is pointed back at the AniNIX/Yggdrasil's SFTP service.
Configuration is done in [the app](http://10.0.1.8:8334/admin/). A unique password should be configured, and then the only authorized backend is SFTP with passthrough authentication on the 'username_and_password' strategy. The SFTP host is then jailed as AniNIX/Yggdrasil's internal IP and port, with the `{{ .user }}` and `{{ .password }}` attributes populated.
This app can be proxied to the outside world and protected by encryption & a web-application firewall. This happens through [a WebServer configuration file](/AniNIX/Ubiqtorate/src/branch/main/roles/WebServer/files/conf.d/Core/adhan.conf).
## Backups
No backup is needed.

View File

@ -1,22 +0,0 @@
server {
listen 443 ssl http2;
server_name cyberbrain.aninix.net;
include sec.conf;
include default.csp.conf;
include letsencrypt.conf;
location /
{
auth_basic "Cyberbrain";
auth_basic_user_file ../passwords/cyberbrain.htpasswd;
proxy_pass http://127.0.0.1:8822;
proxy_http_version 1.1;
proxy_read_timeout 300;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-PORT $remote_port;
}
}

View File

@ -1,10 +0,0 @@
[Unit]
Description=AniNIX/Cyberbrain | SSH Web Front End, powered by python-webssh
[Service]
User=webssh
EnvironmentFile=/etc/conf.d/webssh
ExecStart=/usr/bin/wssh $WEBSSH_ARGS
[Install]
WantedBy=multi-user.target

View File

@ -1,71 +0,0 @@
---
- name: Install python-webssh
become: yes
package:
name: python-webssh
state: present
- name: Standardize the servicefile
become: yes
register: servicefile
copy:
src: cyberbrain.service
dest: /usr/lib/systemd/system/cyberbrain.service
owner: root
group: root
mode: 0644
- name: Ensure default webssh service file is off.
become: yes
service:
name: webssh
state: stopped
enabled: no
- systemd:
daemon_reload: true
when: servicefile.changed
become: yes
- name: Ensure service is restarted
when: servicefile.changed
become: yes
service:
name: cyberbrain.service
enabled: yes
state: started
- name: Ensure service is started
when: not servicefile.changed
become: yes
service:
name: cyberbrain.service
enabled: yes
state: started
- name: Add the webserver conf file
become: yes
register: webserver_conf
copy:
src: cyberbrain.conf
dest: /opt/openresty/nginx/conf.d/cyberbrain.conf
owner: root
group: http
mode: 0750
- name: Ensure the password file is seeded
become: yes
template:
src: cyberbrain.htpasswd.j2
dest: /opt/openresty/nginx/passwords/cyberbrain.htpasswd
owner: root
group: http
mode: 0750
- name: Reload openresty
become: yes
when: webserver_conf.changed
service:
name: openresty.service
state: reloaded

View File

@ -1 +0,0 @@
cyberbrain:{PLAIN}{{ passwords.Cyberbrain }}

View File

@ -1,16 +1,3 @@
<!-- Google Analytics -->
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-18148792-3']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<!-- Replace Gitea icon with AniNIX -->
<script type="text/javascript">
document.getElementById('navbar').children[0].children[0].children[0].src="/assets/img/AniNIX.png";
@ -20,5 +7,3 @@ _gaq.push(['_trackPageview']);
document.getElementById("pwdchange").setAttribute("target","_blank");
document.getElementById("chat").setAttribute("target","_blank");
</script>

View File

@ -448,7 +448,7 @@ PROVIDER_CONFIG = data/sessions
; Session cookie name
COOKIE_NAME = i_like_gitea
; If you use session in https only, default is false
COOKIE_SECURE = false
COOKIE_SECURE = true
; Enable set cookie, default is true
ENABLE_SET_COOKIE = true
; Session GC time interval in seconds, default is 86400 (1 day)

View File

@ -16,21 +16,21 @@
- name: Tap ArchLinux network config
become: yes
when: tap is defined and not static is defined
#when: tap is defined and not static is defined
template:
src: netctl-tap is defined.j2
src: netctl-tap.j2
dest: "/etc/netctl/{{ ipinterface }}"
- name: Bridge ArchLinux network config
become: yes
when: tap is defined and not static is defined
#when: tap is defined and not static is defined
template:
src: netctl-bond.j2
dest: "/etc/netctl/br0"
- name: Tunnel ArchLinux network config
become: yes
when: tap is defined and not static is defined
#when: tap is defined and not static is defined
copy:
src: netctl-tun
dest: "/etc/netctl/tun0"

View File

@ -30,26 +30,6 @@
- root
- "{{ ansible_user_id }}"
- name: Base packages
vars:
ansible_become_method: su
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
package:
name:
- bash
- sudo
- git
- tmux
- vim
- sysstat
- iotop
- lsof
- rsync
- xfsprogs
state: present
update_cache: yes
- name: Ensure deploy user has sudo permissions.
vars:
ansible_become_method: su
@ -105,6 +85,13 @@
group: root
mode: 0644
- name: Import AniNIX GPG key
vars:
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
command: /bin/bash -c 'if [ ! -f /usr/share/pacman/keyrings/aninix.gpg ]; then mkdir /tmp/aninix; curl -s https://aninix.net/AniNIX/ShadowArch/raw/branch/main/EtcFiles/aninix.gpg > /tmp/aninix/pubring.gpg; pacman-key --import /tmp/aninix; pacman-key --lsign 904DE6275579CB589D85720C1CC1E3F4ED06F296; fi'
when: ansible_os_family == "Archlinux"
- name: Set up apt sources.list
vars:
ansible_become_password: "{{ passwords[inventory_hostname] }}"
@ -120,6 +107,28 @@
mode: 0644
when: ansible_os_family == "Debian"
- name: Base packages
vars:
ansible_become_method: su
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
package:
name:
- bash
- sudo
- git
- tmux
- vim
- sysstat
- iotop
- lsof
- rsync
- xfsprogs
- man-db
- man-pages
state: present
update_cache: yes
- name: Install ShadowArch (ArchLinux)
vars:
ansible_become_password: "{{ passwords[inventory_hostname] }}"

View File

@ -0,0 +1,2 @@
check program cyberpower with path "/etc/monit.d/scripts/check-cyberpower"
if status != 0 for 5 times within 5 cycles then exec "/etc/monit.d/scripts/critical Host is on UPS power!"

View File

@ -1 +1,2 @@
include "/etc/monit.d/checks/system"
include "/etc/monit.d/checks/cyberpower"

View File

@ -0,0 +1,6 @@
#!/bin/bash
if [ `pwrstat -status | sed 's/^\s\+//' | grep -E ^State | awk '{ print $2; }'` != 'Normal' ]; then
exit 2;
fi
exit 0

View File

@ -10,6 +10,16 @@ Of security note are the default.csp.conf and sec.conf files in [the conf folder
**Please note:** We offer a redirect on www.aninix.net and http://aninix.net:80/ only as a legacy convenience as browsers do not yet support 443 by default -- no data is transmitted on these. When the webhosting community acknowledges the death of the empty www. subdomain and the necessity of encryption, we will drop these. However, for usability, we include them for now.
## Apps
We include `files/apps` here for apps that are too small to warrant their own project. These include things like:
* AniNIX/Scratch -- a scratchpad in cache
* AniNIX/BlackPage -- a blackout page for the monitor
* AniNIX/WhatIsMyIP -- an IP-returning service, reducing the load on upstream [WhatIsMyIP](https://whatismyip.com)
These apps must be short -- a hook is in place to ensure this.
# Available Clients
Users should use [Chrome](http://google.com/chrome/browser/desktop/) where possible, though other standard browsers will work. [AniNIX/Maat](https://maat.aninix.net) builds google-chrome as a package for ArchLinux.

View File

@ -0,0 +1,75 @@
<?php
# File: routing.php
#
# Description: This page is to render an example printout for students to test routing
# from within the network emulation software.
#
# Package: 25U MOS-T Tools
# Copyright: DoD
#
# Author: SPC Ford with 421 RTI 25U MOS-T Class 001-24
echo '<html>
<head>
<title>25U Routing Practice</title>
</head>
<body>';
//Example picture
echo '<img src=/assets/25u/example_network2.png style="width:100%;height:auto;" />';
echo '<h3>IP Chart</h3>';
// RFC1918
$seed = rand(1,3);
switch($seed) {
case 1: $base="10.".rand(0,255) ; break;
case 2: $base="172.".rand(16,31) ; break;
case 3: $base="192.168" ; break;
}
// Random Class C
$thirdoctet=rand(0,255);
// Find three nonidentical nets
$netid1=rand(0,7);
$netid2=$netid1;
while ($netid2==$netid1) {
$netid2=rand(0,7);
}
$netid3=$netid1;
while ($netid1==$netid3 OR $netid2==$netid3) {
$netid3=rand(0,7);
}
// Format display
$displaynet1 = $base.'.'.$thirdoctet.'.'.($netid1*32).'/'.rand(27,29);
$displaynet2 = $base.'.'.$thirdoctet.'.'.($netid2*32).'/'.rand(27,29);
$displaynet3 = $base.'.'.$thirdoctet.'.'.($netid3*32).'/30';
// Render
echo '<table style="width:100%;"><tr><th style="width:150px;">Device</th><th style="width:150px;">Interface</th><th style="width:150px;">NetID</th><th style="width:150px;">IP Address</th></tr>';
echo '
<tr><th style="border: 1px solid;" colspan=4>Network 3</th style="border: 1px solid;"></tr>
<tr><td style="border:1px solid;">RTR1</td style="border:1px solid;"><td style="border:1px solid;">G0/1</td style="border:1px solid;"><td style="border:1px solid;">'.$displaynet3.'<td style="border:1px solid;">&nbsp;</td style="border:1px solid;"></tr>
<tr><td style="border:1px solid;">RTR2</td style="border:1px solid;"><td style="border:1px solid;">G0/1</td style="border:1px solid;"><td style="border:1px solid;">'.$displaynet3.'<td style="border:1px solid;">&nbsp;</td style="border:1px solid;"></tr>
<tr><th style="border: 1px solid;" colspan=4>Network 1</th style="border: 1px solid;"></tr>
<tr><td style="border:1px solid;">RTR1</td style="border:1px solid;"><td style="border:1px solid;">G0/0</td style="border:1px solid;"><td style="border:1px solid;">'.$displaynet1.'<td style="border:1px solid;">&nbsp;</td style="border:1px solid;"></tr>
<tr><td style="border:1px solid;">SW1</td style="border:1px solid;"><td style="border:1px solid;">VLAN 1</td style="border:1px solid;"><td style="border:1px solid;">'.$displaynet1.'<td style="border:1px solid;">&nbsp;</td style="border:1px solid;"></tr>
<tr><td style="border:1px solid;">PC1</td style="border:1px solid;"><td style="border:1px solid;">NIC</td style="border:1px solid;"><td style="border:1px solid;">'.$displaynet1.'<td style="border:1px solid;">&nbsp;</td style="border:1px solid;"></tr>
<tr><td style="border:1px solid;">WAP1</td style="border:1px solid;"><td style="border:1px solid;">NIC</td style="border:1px solid;"><td style="border:1px solid;">'.$displaynet1.'<td style="border:1px solid;">&nbsp;</td style="border:1px solid;"></tr>
<tr><td style="border:1px solid;">LTP1</td style="border:1px solid;"><td style="border:1px solid;">Wireless</td style="border:1px solid;"><td style="border:1px solid;">'.$displaynet1.'<td style="border:1px solid;">&nbsp;</td style="border:1px solid;"></tr>
<tr><td style="border:1px solid;">Printer 1</td style="border:1px solid;"><td style="border:1px solid;">Wireless</td style="border:1px solid;"><td style="border:1px solid;">'.$displaynet1.'<td style="border:1px solid;">&nbsp;</td style="border:1px solid;"></tr>
<tr><th style="border: 1px solid;" colspan=4>Network 2</th style="border: 1px solid;"></tr>
<tr><td style="border:1px solid;">RTR2</td style="border:1px solid;"><td style="border:1px solid;">G0/0</td style="border:1px solid;"><td style="border:1px solid;">'.$displaynet2.'<td style="border:1px solid;">&nbsp;</td style="border:1px solid;"></tr>
<tr><td style="border:1px solid;">SW2</td style="border:1px solid;"><td style="border:1px solid;">VLAN 1</td style="border:1px solid;"><td style="border:1px solid;">'.$displaynet2.'<td style="border:1px solid;">&nbsp;</td style="border:1px solid;"></tr>
<tr><td style="border:1px solid;">PC2</td style="border:1px solid;"><td style="border:1px solid;">NIC</td style="border:1px solid;"><td style="border:1px solid;">'.$displaynet2.'<td style="border:1px solid;">&nbsp;</td style="border:1px solid;"></tr>
<tr><td style="border:1px solid;">WAP2</td style="border:1px solid;"><td style="border:1px solid;">NIC</td style="border:1px solid;"><td style="border:1px solid;">'.$displaynet2.'<td style="border:1px solid;">&nbsp;</td style="border:1px solid;"></tr>
<tr><td style="border:1px solid;">LTP2</td style="border:1px solid;"><td style="border:1px solid;">Wireless</td style="border:1px solid;"><td style="border:1px solid;">'.$displaynet2.'<td style="border:1px solid;">&nbsp;</td style="border:1px solid;"></tr>
<tr><td style="border:1px solid;">Printer 2</td style="border:1px solid;"><td style="border:1px solid;">Wireless</td style="border:1px solid;"><td style="border:1px solid;">'.$displaynet2.'<td style="border:1px solid;">&nbsp;</td style="border:1px solid;"></tr>
';
echo '</table>';
echo '</body></html>';

View File

@ -0,0 +1,56 @@
<?php
# File: subnetting.php
#
# Description: This page is to render an example printout for students to test subnetting
# and binary conversions by hand.
#
# Package: 25U MOS-T Tools
# Copyright: DoD
#
# Author: SPC Ford with 421 RTI 25U MOS-T Class 001-24
echo '<html>
<head>
<title>25U Subnetting Practice</title>
</head>
<body>';
// Binary conversions
echo '<h3>Convert the following to binary:</h3>';
for ($x = 0; $x <= 3; $x++) {
echo '<p>'.rand(0,256).' ____________________</p>';
}
// Decimal conversions
echo '<h3>Convert the following to decimal:</h3>';
for ($x = 0; $x <= 3; $x++) {
echo '<p>';
for ($y = 0; $y <= 7; $y++) {
echo rand(0,1);
}
echo ' ____________________</p>';
}
// CIDRs
echo '<h3>Convert the following slash notations to decimal and binary:</h3><table style="width:100%;"><tr><th style="width:30%;">Slash</th><th style="width:30%;">Decimal</th><th style="width:30%;">Binary</th></tr>';
for ($x = 0; $x <= 3; $x++) {
echo '<tr><td style="border: 1px solid;">'.rand(16,32).'</td><td style="border: 1px solid;">&nbsp;</td><td style="border: 1px solid;">&nbsp;</td>';
}
echo '</table>';
//Subnets
echo '<h3>Identify the following for these CIDRs:</h3>';
echo '<table style="width:100%;"><tr><th style="width:150px;">IP/CIDR</th><th style="width:150px;">SM</th><th style="width:150px;">NetID</th><th style="width:150px;">Host Range</th><th style="width:150px;">Broadcast</th><th style="width:150px;">Gateway</th><th style="width:150px;">Increment</th></tr>';
for ($x = 0; $x <= 6; $x++) {
echo '<tr><td style="border: 1px solid;">'.rand(0,256).'.'.rand(0,256).'.'.rand(0,256).'.'.rand(0,256).'/'.rand(16,32).'</td><td style="border: 1px solid;">&nbsp;</td><td style="border: 1px solid;">&nbsp;</td><td style="border: 1px solid;">&nbsp;</td><td style="border: 1px solid;">&nbsp;</td><td style="border: 1px solid;">&nbsp;</td><td style="border: 1px solid;">&nbsp;</td></tr>';
}
echo '</table>';
echo '<h3>Bonus: Calculate the three subnets that follow each of the above.</h3>';
echo '</body></html>';

View File

@ -0,0 +1,9 @@
<html>
<head>
<title>Hit F11 to black screen</title>
<link rel="stylesheet" type="text/css" href="../style.css">
</head>
<body>
</body>
</html>

View File

@ -0,0 +1,6 @@
<html>
<body>
<h4>WARNING: Nothing will be saved. Copy to a text file for persistence.</h4>
<form><textarea cols=80 rows=35></textarea></form>
</body>
</html>

View File

@ -0,0 +1,3 @@
<?php
echo $_SERVER['REMOTE_ADDR'];
?>

View File

@ -1,48 +0,0 @@
server {
listen 443 ssl;
server_name cyberbrain.aninix.net;
include local.conf;
root /usr/share/webapps/;
client_max_body_size 5m;
client_body_timeout 60;
include ../conf.d/fastcgi7.config;
location /mediawiki-gb/ {
try_files $uri $uri/ @rewrite;
rewrite ^/mediawiki-gb/(.*)$ /mediawiki/index.php?title=$1&$args;
rewrite ^$ /mediawiki-gb/Main_Page;
rewrite ^/$ /mediawiki-gb/Main_Page;
rewrite ^mediawiki-gb$ /mediawiki-gb/Main_Page;
rewrite ^mediawiki-gb/$ /mediawiki-gb/Main_Page;
}
location /mediawiki-ma/ {
try_files $uri $uri/ @rewrite;
rewrite ^/mediawiki-ma/(.*)$ /mediawiki/index.php?title=$1&$args;
rewrite ^$ /mediawiki-ma/Main_Page;
rewrite ^/$ /mediawiki-ma/Main_Page;
rewrite ^mediawiki-ma$ /mediawiki-ma/Main_Page;
rewrite ^mediawiki-ma/$ /mediawiki-ma/Main_Page;
}
location ^~ /maintenance/ {
return 403;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
try_files $uri /mediawiki/index.php;
expires max;
log_not_found off;
}
location ^~ /cache/ {
deny all;
}
include letsencrypt.conf;
}

View File

@ -2,10 +2,10 @@ server {
listen 443 ssl http2;
server_name default_server;
include sec.conf;
include default.csp.conf;
include conf/sec.conf;
include conf/default.csp.conf;
include letsencrypt.conf;
include conf/letsencrypt.conf;
location / {
@ -18,6 +18,10 @@ server {
proxy_pass http://127.0.0.1:3000;
}
location /shadowarch {
rewrite /shadowarch /AniNIX/ShadowArch/raw/branch/main/EtcFiles/shadowarch;
}
location /aninix.xml {
proxy_hide_header Content-Type;
add_header content-type "application/atom+xml";
@ -30,8 +34,17 @@ server {
rewrite /martialarts/maqotw.xml /MartialArts/Wiki/raw/branch/main/rss/maqotw.xml;
}
location /25u {
include conf.d/fastcgi.config;
root /usr/share/webapps/aninix/;
location ~* 25u {
try_files $uri /25u_subnetting.php;
expires max;
}
}
location /whatismyip {
include ../conf.d/fastcgi.config;
include conf.d/fastcgi.config;
root /usr/share/webapps/aninix/;
location ~* whatismyip {
try_files $uri /whatismyip.php;
@ -44,14 +57,20 @@ server {
try_files $uri /blackpage.html;
}
location /scratch {
root /usr/share/webapps/aninix/;
try_files $uri /scratch.html;
}
}
server {
listen 443 ssl http2;
server_name foundation.aninix.net;
include sec.conf;
include letsencrypt.conf;
include default.csp.conf;
include conf/sec.conf;
include conf/letsencrypt.conf;
include conf/default.csp.conf;
location / {
rewrite ^/(.*)$ https://aninix.net/$1 permanent;

View File

@ -2,8 +2,8 @@ server {
listen 443 ssl http2;
server_name adhan.aninix.net;
include sec.conf;
include default.csp.conf;
include conf/sec.conf;
include conf/default.csp.conf;
location /
{

View File

@ -0,0 +1,15 @@
server {
listen 443 ssl;
server_name cyberbrain.aninix.net;
location ^~ /admin {
deny all;
}
location / {
proxy_pass http://10.0.1.8:8334;
}
include conf/letsencrypt.conf;
}

View File

@ -8,10 +8,10 @@ server {
listen 443 ssl;
server_name geth.aninix.net;
include sec.conf;
# include default.csp.conf;
# include local.conf;
include letsencrypt.conf;
include conf/sec.conf;
# include conf/default.csp.conf;
# include conf/local.conf;
include conf/letsencrypt.conf;
location /
{

View File

@ -3,8 +3,8 @@ server {
listen 444 ssl http2;
server_name sharingan.aninix.net;
include sec.conf;
# include default.csp.conf;
include conf/sec.conf;
# include conf/default.csp.conf;
location /
{

View File

@ -2,9 +2,9 @@ server {
listen 443 ssl http2;
server_name irc.aninix.net;
include sec.conf;
include default.csp.conf;
include letsencrypt.conf;
include conf/sec.conf;
include conf/default.csp.conf;
include conf/letsencrypt.conf;
location /
{

View File

@ -2,14 +2,14 @@ server {
listen 443 ssl;
server_name lykos.aninix.net;
# include local.conf;
# include conf/local.conf;
root /usr/share/webapps/;
client_max_body_size 5m;
client_body_timeout 60;
include ../conf.d/fastcgi.config;
include conf.d/fastcgi.config;
location / {
try_files $uri $uri/ @rewrite;
@ -34,6 +34,6 @@ server {
deny all;
}
include letsencrypt.conf;
include conf/letsencrypt.conf;
}

View File

@ -2,13 +2,12 @@ server {
listen 443 ssl http2;
server_name maat.aninix.net;
include sec.conf;
include default.csp.conf;
include letsencrypt.conf;
include conf/sec.conf;
include conf/default.csp.conf;
include conf/letsencrypt.conf;
location /
{
try_files $uri /index.html
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;

View File

@ -2,14 +2,14 @@ server {
listen 443 ssl http2;
server_name password.aninix.net;
include sec.conf;
include default.csp.conf;
include letsencrypt.conf;
include conf/sec.conf;
include conf/default.csp.conf;
include conf/letsencrypt.conf;
location / {
root /usr/share/webapps/self-service-password/htdocs/;
# https://ltb-project.org/documentation/self-service-password/1.3/config_nginx
# https://ltb-project.org/documentation/self-service-password/1config_nginx
index index.php index.html index.htm;
# Disable sendfile as per https://docs.vagrantup.com/v2/synced-folders/virtualbox.html
@ -28,7 +28,7 @@ server {
#error_log /dev/stdout warn;
#access_log /dev/stdout info;
include ../conf.d/fastcgi.config;
include conf.d/fastcgi.config;
}
# deny access to . files, for security

View File

@ -3,10 +3,10 @@ server {
listen 443 ssl http2;
server_name sharingan.aninix.net;
include sec.conf;
# include default.csp.conf;
include local.conf;
include letsencrypt.conf;
include conf/sec.conf;
# include conf/default.csp.conf;
include conf/local.conf;
include conf/letsencrypt.conf;
location /

View File

@ -2,11 +2,11 @@ server {
listen 443 ssl;
server_name singularity.aninix.net;
include sec.conf;
include default.csp.conf;
include letsencrypt.conf;
include conf/sec.conf;
include conf/default.csp.conf;
include conf/letsencrypt.conf;
include ../conf.d/fastcgi.config;
include conf.d/fastcgi.config;
root /usr/share/webapps/tt-rss/;

View File

@ -2,9 +2,9 @@ server {
listen 443 ssl;
server_name travelpawscvt.com;
#include local.conf;
include letsencrypt.conf;
include ../conf.d/fastcgi.config;
#include conf/local.conf;
include conf/letsencrypt.conf;
include conf.d/fastcgi.config;
root /opt/travelpawscvt;

View File

@ -2,8 +2,8 @@ server {
listen 443 ssl http2;
server_name wolfpack.aninix.net;
include sec.conf;
include default.csp.conf;
include conf/sec.conf;
include conf/default.csp.conf;
location /
{
@ -12,5 +12,5 @@ server {
autoindex_format html;
}
include letsencrypt.conf;
include conf/letsencrypt.conf;
}

View File

@ -3,9 +3,9 @@ server {
listen 443 ssl http2;
server_name yggdrasil.aninix.net;
include sec.conf;
include letsencrypt.conf;
# include default.csp.conf;
include conf/sec.conf;
include conf/letsencrypt.conf;
# include conf/default.csp.conf;
location /
{

View File

@ -1 +1,3 @@
add_header "Content-Security-Policy" "default-src data: 'self' aninix.net foundation.aninix.net; script-src foundation.aninix.net www.gstatic.com www.google.com js.stripe.com unsafe-inline ssl.google-analytics.com 'self' aninix.net foundation.aninix.net data: 'unsafe-inline' 'unsafe-eval'; style-src foundation.aninix.net 'self' aninix.net foundation.aninix.net 'unsafe-inline' fonts.googleapis.com fonts.gstatic.com; img-src foundation.aninix.net 'self' aninix.net foundation.aninix.net upload.wikimedia.org commons.wikimedia.org creativecommons.org www.w3.org stripe.com ssl.google-analytics.com; font-src fonts.gstatic.com data: 'self' aninix.net foundation.aninix.net; connect-src ssl.google-analytics.com js.stripe.com mb3admin.com 'self' aninix.net foundation.aninix.net; media-src blob: 'self' aninix.net foundation.aninix.net ; child-src blob: 'self' js.stripe.com aninix.net foundation.aninix.net www.google.com; form-action 'self' aninix.net foundation.aninix.net; upgrade-insecure-requests;";
add_header "Content-Security-Policy" "default-src data: 'self' aninix.net foundation.aninix.net; script-src foundation.aninix.net 'self' aninix.net data: 'unsafe-inline' 'unsafe-eval'; style-src foundation.aninix.net 'self' aninix.net foundation.aninix.net 'unsafe-inline'; img-src foundation.aninix.net 'self' aninix.net; font-src data: 'self' aninix.net foundation.aninix.net; connect-src mb3admin.com 'self' aninix.net foundation.aninix.net; media-src blob: 'self' aninix.net foundation.aninix.net ; child-src blob: 'self' aninix.net foundation.aninix.net; form-action 'self' aninix.net foundation.aninix.net; upgrade-insecure-requests; base-uri 'self'; frame-ancestors 'self'; default-src 'none'; ";
# Gitea requires unsafe-inline style sources for label colors
# TT-RSS requires unsafe-inline/unsafe-eval for its javascript dojo.js integrations.

View File

@ -0,0 +1,8 @@
/var/log/modsec_audit.log {
missingok
notifempty
create 640 http http
sharedscripts
compress
endscript
}

968
roles/WebServer/files/modsec.conf Executable file
View File

@ -0,0 +1,968 @@
# -- Rule engine initialization ----------------------------------------------
# Enable ModSecurity, attaching it to every transaction. Use detection
# only to start with, because that minimises the chances of post-installation
# disruption.
#
SecRuleEngine DetectionOnly
# -- Request body handling ---------------------------------------------------
# Allow ModSecurity to access request bodies. If you don't, ModSecurity
# won't be able to see any POST parameters, which opens a large security
# hole for attackers to exploit.
#
SecRequestBodyAccess On
# Enable XML request body parser.
# Initiate XML Processor in case of xml content-type
#
SecRule REQUEST_HEADERS:Content-Type "^(?:application(?:/soap\+|/)|text/)xml" \
"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"
# Enable JSON request body parser.
# Initiate JSON Processor in case of JSON content-type; change accordingly
# if your application does not use 'application/json'
#
SecRule REQUEST_HEADERS:Content-Type "^application/json" \
"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"
# Sample rule to enable JSON request body parser for more subtypes.
# Uncomment or adapt this rule if you want to engage the JSON
# Processor for "+json" subtypes
#
#SecRule REQUEST_HEADERS:Content-Type "^application/[a-z0-9.-]+[+]json" \
# "id:'200006',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"
# Maximum request body size we will accept for buffering. If you support
# file uploads then the value given on the first line has to be as large
# as the largest file you are willing to accept. The second value refers
# to the size of data, with files excluded. You want to keep that value as
# low as practical.
#
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
# What to do if the request body size is above our configured limit.
# Keep in mind that this setting will automatically be set to ProcessPartial
# when SecRuleEngine is set to DetectionOnly mode in order to minimize
# disruptions when initially deploying ModSecurity.
#
SecRequestBodyLimitAction Reject
# Maximum parsing depth allowed for JSON objects. You want to keep this
# value as low as practical.
#
SecRequestBodyJsonDepthLimit 512
# Maximum number of args allowed per request. You want to keep this
# value as low as practical. The value should match that in rule 200007.
SecArgumentsLimit 1000
# If SecArgumentsLimit has been set, you probably want to reject any
# request body that has only been partly parsed. The value used in this
# rule should match what was used with SecArgumentsLimit
SecRule &ARGS "@ge 1000" \
"id:'200007', phase:2,t:none,log,deny,status:400,msg:'Failed to fully parse request body due to large argument count',severity:2"
# Verify that we've correctly processed the request body.
# As a rule of thumb, when failing to process a request body
# you should reject the request (when deployed in blocking mode)
# or log a high-severity alert (when deployed in detection-only mode).
#
SecRule REQBODY_ERROR "!@eq 0" \
"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"
# By default be strict with what we accept in the multipart/form-data
# request body. If the rule below proves to be too strict for your
# environment consider changing it to detection-only. You are encouraged
# _not_ to remove it altogether.
#
SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
"id:'200003',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed strict validation: \
PE %{REQBODY_PROCESSOR_ERROR}, \
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
DB %{MULTIPART_DATA_BEFORE}, \
DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_MISSING_SEMICOLON}, \
IQ %{MULTIPART_INVALID_QUOTING}, \
IP %{MULTIPART_INVALID_PART}, \
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'"
# Did we see anything that might be a boundary?
#
# Here is a short description about the ModSecurity Multipart parser: the
# parser returns with value 0, if all "boundary-like" line matches with
# the boundary string which given in MIME header. In any other cases it returns
# with different value, eg. 1 or 2.
#
# The RFC 1341 descript the multipart content-type and its syntax must contains
# only three mandatory lines (above the content):
# * Content-Type: multipart/mixed; boundary=BOUNDARY_STRING
# * --BOUNDARY_STRING
# * --BOUNDARY_STRING--
#
# First line indicates, that this is a multipart content, second shows that
# here starts a part of the multipart content, third shows the end of content.
#
# If there are any other lines, which starts with "--", then it should be
# another boundary id - or not.
#
# After 3.0.3, there are two kinds of types of boundary errors: strict and permissive.
#
# If multipart content contains the three necessary lines with correct order, but
# there are one or more lines with "--", then parser returns with value 2 (non-zero).
#
# If some of the necessary lines (usually the start or end) misses, or the order
# is wrong, then parser returns with value 1 (also a non-zero).
#
# You can choose, which one is what you need. The example below contains the
# 'strict' mode, which means if there are any lines with start of "--", then
# ModSecurity blocked the content. But the next, commented example contains
# the 'permissive' mode, then you check only if the necessary lines exists in
# correct order. Whit this, you can enable to upload PEM files (eg "----BEGIN.."),
# or other text files, which contains eg. HTTP headers.
#
# The difference is only the operator - in strict mode (first) the content blocked
# in case of any non-zero value. In permissive mode (second, commented) the
# content blocked only if the value is explicit 1. If it 0 or 2, the content will
# allowed.
#
#
# See #1747 and #1924 for further information on the possible values for
# MULTIPART_UNMATCHED_BOUNDARY.
#
SecRule MULTIPART_UNMATCHED_BOUNDARY "@eq 1" \
"id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"
# PCRE Tuning
# We want to avoid a potential RegEx DoS condition
#
SecPcreMatchLimit 1000
SecPcreMatchLimitRecursion 1000
# Some internal errors will set flags in TX and we will need to look for these.
# All of these are prefixed with "MSC_". The following flags currently exist:
#
# MSC_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded.
#
SecRule TX:/^MSC_/ "!@streq 0" \
"id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"
# -- Response body handling --------------------------------------------------
# Allow ModSecurity to access response bodies.
# You should have this directive enabled in order to identify errors
# and data leakage issues.
#
# Do keep in mind that enabling this directive does increases both
# memory consumption and response latency.
#
SecResponseBodyAccess On
# Which response MIME types do you want to inspect? You should adjust the
# configuration below to catch documents but avoid static files
# (e.g., images and archives).
#
SecResponseBodyMimeType text/plain text/html text/xml
# Buffer response bodies of up to 512 KB in length.
SecResponseBodyLimit 524288
# What happens when we encounter a response body larger than the configured
# limit? By default, we process what we have and let the rest through.
# That's somewhat less secure, but does not break any legitimate pages.
#
SecResponseBodyLimitAction ProcessPartial
# -- Filesystem configuration ------------------------------------------------
# The location where ModSecurity stores temporary files (for example, when
# it needs to handle a file upload that is larger than the configured limit).
#
# This default setting is chosen due to all systems have /tmp available however,
# this is less than ideal. It is recommended that you specify a location that's private.
#
SecTmpDir /var/log/modsec/tmp
# The location where ModSecurity will keep its persistent data. This default setting
# is chosen due to all systems have /tmp available however, it
# too should be updated to a place that other users can't access.
#
SecDataDir /var/log/modsec/data/
# -- File uploads handling configuration -------------------------------------
# The location where ModSecurity stores intercepted uploaded files. This
# location must be private to ModSecurity. You don't want other users on
# the server to access the files, do you?
#
SecUploadDir /opt/modsecurity/var/upload/
# By default, only keep the files that were determined to be unusual
# in some way (by an external inspection script). For this to work you
# will also need at least one file inspection rule.
#
SecUploadKeepFiles Off
# Uploaded files are by default created with permissions that do not allow
# any other user to access them. You may need to relax that if you want to
# interface ModSecurity to an external program (e.g., an anti-virus).
#
SecUploadFileMode 0600
# -- Debug log configuration -------------------------------------------------
# The default debug log configuration is to duplicate the error, warning
# and notice messages from the error log.
#
SecDebugLog /var/log/modsec/debug.log
SecDebugLogLevel 3
# -- Audit log configuration -------------------------------------------------
# Log the transactions that are marked by a rule, as well as those that
# trigger a server error (determined by a 5xx or 4xx, excluding 404,
# level response status codes).
#
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
# Log everything we know about a transaction.
SecAuditLogParts ABIJDEFHZ
# Use a single file for logging. This is much easier to look at, but
# assumes that you will use the audit log only ocassionally.
#
SecAuditLogType Serial
SecAuditLog /var/log/modsec_audit.log
# Specify the path for concurrent audit logging.
SecAuditLogStorageDir /var/log/modsec/audit
# -- Miscellaneous -----------------------------------------------------------
# Use the most commonly used application/x-www-form-urlencoded parameter
# separator. There's probably only one application somewhere that uses
# something else so don't expect to change this value.
#
SecArgumentSeparator &
# Settle on version 0 (zero) cookies, as that is what most applications
# use. Using an incorrect cookie version may open your installation to
# evasion attacks (against the rules that examine named cookies).
#
SecCookieFormat 0
# Specify your Unicode Code Point.
# This mapping is used by the t:urlDecodeUni transformation function
# to properly map encoded data to your language. Properly setting
# these directives helps to reduce false positives and negatives.
#
#SecUnicodeMapFile unicode.mapping 20127
# Improve the quality of ModSecurity by sharing information about your
# current ModSecurity version and dependencies versions.
# The following information will be shared: ModSecurity version,
# Web Server version, APR version, PCRE version, Lua version, Libxml2
# version, Anonymous unique id for host.
SecStatusEngine On
# ------------------------------------------------------------------------
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
#
# The OWASP ModSecurity Core Rule Set is distributed under
# Apache Software License (ASL) version 2
# Please see the enclosed LICENSE file for full details.
# ------------------------------------------------------------------------
#
# -- [[ Introduction ]] --------------------------------------------------------
#
# The OWASP ModSecurity Core Rule Set (CRS) is a set of generic attack
# detection rules that provide a base level of protection for any web
# application. They are written for the open source, cross-platform
# ModSecurity Web Application Firewall.
#
# See also:
# https://coreruleset.org/
# https://github.com/coreruleset/coreruleset
# https://owasp.org/www-project-modsecurity-core-rule-set/
#
#
# -- [[ System Requirements ]] -------------------------------------------------
#
# CRS requires ModSecurity version 2.8.0 or above.
# We recommend to always use the newest ModSecurity version.
#
# The configuration directives/settings in this file are used to control
# the OWASP ModSecurity CRS. These settings do **NOT** configure the main
# ModSecurity settings (modsecurity.conf) such as SecRuleEngine,
# SecRequestBodyAccess, SecAuditEngine, SecDebugLog, and XML processing.
#
# The CRS assumes that modsecurity.conf has been loaded. It is bundled with
# ModSecurity. If you don't have it, you can get it from:
# 2.x: https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v2/master/modsecurity.conf-recommended
# 3.x: https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended
#
# The order of file inclusion in your webserver configuration should always be:
# 1. modsecurity.conf
# 2. crs-setup.conf (this file)
# 3. rules/*.conf (the CRS rule files)
#
# Please refer to the INSTALL file for detailed installation instructions.
#
#
# -- [[ Mode of Operation: Anomaly Scoring vs. Self-Contained ]] ---------------
#
# The CRS can run in two modes:
#
# -- [[ Anomaly Scoring Mode (default) ]] --
# In CRS3, anomaly mode is the default and recommended mode, since it gives the
# most accurate log information and offers the most flexibility in setting your
# blocking policies. It is also called "collaborative detection mode".
# In this mode, each matching rule increases an 'anomaly score'.
# At the conclusion of the inbound rules, and again at the conclusion of the
# outbound rules, the anomaly score is checked, and the blocking evaluation
# rules apply a disruptive action, by default returning an error 403.
#
# -- [[ Self-Contained Mode ]] --
# In this mode, rules apply an action instantly. This was the CRS2 default.
# It can lower resource usage, at the cost of less flexibility in blocking policy
# and less informative audit logs (only the first detected threat is logged).
# Rules inherit the disruptive action that you specify (i.e. deny, drop, etc).
# The first rule that matches will execute this action. In most cases this will
# cause evaluation to stop after the first rule has matched, similar to how many
# IDSs function.
#
# -- [[ Alert Logging Control ]] --
# In the mode configuration, you must also adjust the desired logging options.
# There are three common options for dealing with logging. By default CRS enables
# logging to the webserver error log (or Event viewer) plus detailed logging to
# the ModSecurity audit log (configured under SecAuditLog in modsecurity.conf).
#
# - To log to both error log and ModSecurity audit log file, use: "log,auditlog"
# - To log *only* to the ModSecurity audit log file, use: "nolog,auditlog"
# - To log *only* to the error log file, use: "log,noauditlog"
#
# Examples for the various modes follow.
# You must leave one of the following options enabled.
# Note that you must specify the same line for phase:1 and phase:2.
#
# Default: Anomaly Scoring mode, log to error log, log to ModSecurity audit log
# - By default, offending requests are blocked with an error 403 response.
# - To change the disruptive action, see RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example
# and review section 'Changing the Disruptive Action for Anomaly Mode'.
# - In Apache, you can use ErrorDocument to show a friendly error page or
# perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html
#
SecDefaultAction "phase:1,log,auditlog,pass"
SecDefaultAction "phase:2,log,auditlog,pass"
# Example: Anomaly Scoring mode, log only to ModSecurity audit log
# - By default, offending requests are blocked with an error 403 response.
# - To change the disruptive action, see RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example
# and review section 'Changing the Disruptive Action for Anomaly Mode'.
# - In Apache, you can use ErrorDocument to show a friendly error page or
# perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html
#
# SecDefaultAction "phase:1,nolog,auditlog,pass"
# SecDefaultAction "phase:2,nolog,auditlog,pass"
# Example: Self-contained mode, return error 403 on blocking
# - In this configuration the default disruptive action becomes 'deny'. After a
# rule triggers, it will stop processing the request and return an error 403.
# - You can also use a different error status, such as 404, 406, et cetera.
# - In Apache, you can use ErrorDocument to show a friendly error page or
# perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html
#
# SecDefaultAction "phase:1,log,auditlog,deny,status:403"
# SecDefaultAction "phase:2,log,auditlog,deny,status:403"
# Example: Self-contained mode, redirect back to homepage on blocking
# - In this configuration the 'tag' action includes the Host header data in the
# log. This helps to identify which virtual host triggered the rule (if any).
# - Note that this might cause redirect loops in some situations; for example
# if a Cookie or User-Agent header is blocked, it will also be blocked when
# the client subsequently tries to access the homepage. You can also redirect
# to another custom URL.
# SecDefaultAction "phase:1,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'"
# SecDefaultAction "phase:2,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'"
#
# -- [[ Paranoia Level Initialization ]] ---------------------------------------
#
# The Paranoia Level (PL) setting allows you to choose the desired level
# of rule checks that will add to your anomaly scores.
#
# With each paranoia level increase, the CRS enables additional rules
# giving you a higher level of security. However, higher paranoia levels
# also increase the possibility of blocking some legitimate traffic due to
# false alarms (also named false positives or FPs). If you use higher
# paranoia levels, it is likely that you will need to add some exclusion
# rules for certain requests and applications receiving complex input.
#
# - A paranoia level of 1 is default. In this level, most core rules
# are enabled. PL1 is advised for beginners, installations
# covering many different sites and applications, and for setups
# with standard security requirements.
# At PL1 you should face FPs rarely. If you encounter FPs, please
# open an issue on the CRS GitHub site and don't forget to attach your
# complete Audit Log record for the request with the issue.
# - Paranoia level 2 includes many extra rules, for instance enabling
# many regexp-based SQL and XSS injection protections, and adding
# extra keywords checked for code injections. PL2 is advised
# for moderate to experienced users desiring more complete coverage
# and for installations with elevated security requirements.
# PL2 comes with some FPs which you need to handle.
# - Paranoia level 3 enables more rules and keyword lists, and tweaks
# limits on special characters used. PL3 is aimed at users experienced
# at the handling of FPs and at installations with a high security
# requirement.
# - Paranoia level 4 further restricts special characters.
# The highest level is advised for experienced users protecting
# installations with very high security requirements. Running PL4 will
# likely produce a very high number of FPs which have to be
# treated before the site can go productive.
#
# All rules will log their PL to the audit log;
# example: [tag "paranoia-level/2"]. This allows you to deduct from the
# audit log how the WAF behavior is affected by paranoia level.
#
# It is important to also look into the variable
# tx.enforce_bodyproc_urlencoded (Enforce Body Processor URLENCODED)
# defined below. Enabling it closes a possible bypass of CRS.
#
# Uncomment this rule to change the default:
#
#SecAction \
# "id:900000,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:tx.blocking_paranoia_level=1"
# It is possible to execute rules from a higher paranoia level but not include
# them in the anomaly scoring. This allows you to take a well-tuned system on
# paranoia level 1 and add rules from paranoia level 2 without having to fear
# the new rules would lead to false positives that raise your score above the
# threshold.
# This optional feature is enabled by uncommenting the following rule and
# setting the tx.detection_paranoia_level.
# Technically, rules up to the level defined in tx.detection_paranoia_level
# will be executed, but only the rules up to tx.blocking_paranoia_level affect the
# anomaly scores.
# By default, tx.detection_paranoia_level is set to tx.blocking_paranoia_level.
# tx.detection_paranoia_level must not be lower than tx.blocking_paranoia_level.
#
# Please notice that setting tx.detection_paranoia_level to a higher paranoia
# level results in a performance impact that is equally high as setting
# tx.blocking_paranoia_level to said level.
#
#SecAction \
# "id:900001,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:tx.detection_paranoia_level=1"
#
# -- [[ Enforce Body Processor URLENCODED ]] -----------------------------------
#
# ModSecurity selects the body processor based on the Content-Type request
# header. But clients are not always setting the Content-Type header for their
# request body payloads. This will leave ModSecurity with limited vision into
# the payload. The variable tx.enforce_bodyproc_urlencoded lets you force the
# URLENCODED body processor in these situations. This is off by default, as it
# implies a change of the behaviour of ModSecurity beyond CRS (the body
# processor applies to all rules, not only CRS) and because it may lead to
# false positives already on paranoia level 1. However, enabling this variable
# closes a possible bypass of CRS so it should be considered.
#
# Uncomment this rule to change the default:
#
#SecAction \
# "id:900010,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:tx.enforce_bodyproc_urlencoded=1"
#
# -- [[ Anomaly Scoring Mode Severity Levels ]] --------------------------------
#
# Each rule in the CRS has an associated severity level.
# These are the default scoring points for each severity level.
# These settings will be used to increment the anomaly score if a rule matches.
# You may adjust these points to your liking, but this is usually not needed.
#
# - CRITICAL severity: Anomaly Score of 5.
# Mostly generated by the application attack rules (93x and 94x files).
# - ERROR severity: Anomaly Score of 4.
# Generated mostly from outbound leakage rules (95x files).
# - WARNING severity: Anomaly Score of 3.
# Generated mostly by malicious client rules (91x files).
# - NOTICE severity: Anomaly Score of 2.
# Generated mostly by the protocol rules (92x files).
#
# In anomaly mode, these scores are cumulative.
# So it's possible for a request to hit multiple rules.
#
# (Note: In this file, we use 'phase:1' to set CRS configuration variables.
# In general, 'phase:request' is used. However, we want to make absolutely sure
# that all configuration variables are set before the CRS rules are processed.)
#
#SecAction \
# "id:900100,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:tx.critical_anomaly_score=5,\
# setvar:tx.error_anomaly_score=4,\
# setvar:tx.warning_anomaly_score=3,\
# setvar:tx.notice_anomaly_score=2"
#
# -- [[ Anomaly Scoring Mode Blocking Threshold Levels ]] ----------------------
#
# Here, you can specify at which cumulative anomaly score an inbound request,
# or outbound response, gets blocked.
#
# Most detected inbound threats will give a critical score of 5.
# Smaller violations, like violations of protocol/standards, carry lower scores.
#
# [ At default value ]
# If you keep the blocking thresholds at the defaults, the CRS will work
# similarly to previous CRS versions: a single critical rule match will cause
# the request to be blocked and logged.
#
# [ Using higher values ]
# If you want to make the CRS less sensitive, you can increase the blocking
# thresholds, for instance to 7 (which would require multiple rule matches
# before blocking) or 10 (which would require at least two critical alerts - or
# a combination of many lesser alerts), or even higher. However, increasing the
# thresholds might cause some attacks to bypass the CRS rules or your policies.
#
# [ New deployment strategy: Starting high and decreasing ]
# It is a common practice to start a fresh CRS installation with elevated
# anomaly scoring thresholds (>100) and then lower the limits as your
# confidence in the setup grows. You may also look into the Sampling
# Percentage section below for a different strategy to ease into a new
# CRS installation.
#
# [ Anomaly Threshold / Paranoia Level Quadrant ]
#
# High Anomaly Limit | High Anomaly Limit
# Low Paranoia Level | High Paranoia Level
# -> Fresh Site | -> Experimental Site
# ------------------------------------------------------
# Low Anomaly Limit | Low Anomaly Limit
# Low Paranoia Level | High Paranoia Level
# -> Standard Site | -> High Security Site
#
# Uncomment this rule to change the defaults:
#
#SecAction \
# "id:900110,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:tx.inbound_anomaly_score_threshold=5,\
# setvar:tx.outbound_anomaly_score_threshold=4"
#
# -- [[ Application Specific Rule Exclusions ]] --------------------------------
#
# CRS 3.x contained exclusion packages to tweak the CRS for use with common
# web applications, lowering the number of false positives.
#
# In CRS 4, these are no longer part of the CRS itself, but they are available
# as "CRS plugins". Some plugins improve support for web applications, and others
# may bring new functionality. Plugins are not installed by default, but can be
# downloaded from the plugin registry:
# https://github.com/coreruleset/plugin-registry
#
# For detailed information about using and installing plugins, please see:
# https://coreruleset.org/docs/configuring/plugins/
#
# -- [[ Anomaly Score Reporting Level ]] ---------------------------------------
#
# When a request is blocked due to the anomaly score meeting or exceeding the
# anomaly threshold then the blocking rule will also report the anomaly score.
# This applies to the separate inbound and outbound anomaly scores.
#
# In phase 5, there are additional rules that can perform additional reporting
# of anomaly scores with a verbosity that depends on the reporting level defined
# below.
#
# By setting the reporting level you control whether you want additional
# reporting beyond the blocking rule or not and, if yes, which requests should
# be covered. The higher the reporting level, the more verbose the reporting is.
#
# There are 6 reporting levels:
#
# 0 - Reporting disabled
# 1 - Reporting for requests with a blocking anomaly score >= a threshold
# 2 - Reporting for requests with a detection anomaly score >= a threshold
# 3 - Reporting for requests with a blocking anomaly score greater than 0
# 4 - Reporting for requests with a detection anomaly score greater than 0
# 5 - Reporting for all requests
#
# Note: Reporting levels 1 and 2 make it possible to differentiate between
# requests that are blocked and requests that are *not* blocked but would have
# been blocked if the blocking PL was equal to detection PL. This may be useful
# for certain FP tuning methodologies, for example moving to a higher PL.
#
# A value of 5 can be useful on platforms where you are interested in logging
# non-scoring requests, yet it is not possible to report this information in
# the request/access log. This applies to Nginx, for example.
#
#SecAction \
# "id:900115,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:tx.reporting_level=4"
#
# -- [[ Early Anomaly Scoring Mode Blocking ]] ------------------------------
#
# The anomaly scores for the request and the responses are generally summed up
# and evaluated at the end of phase:2 and at the end of phase:4 respectively.
# However, it is possible to enable an early evaluation of these anomaly scores
# at the end of phase:1 and at the end of phase:3.
#
# If a request (or a response) hits the anomaly threshold in this early
# evaluation, then blocking happens immediately (if blocking is enabled) and
# the phase 2 (and phase 4 respectively) will no longer be executed.
#
# Enable the rule 900120 that sets the variable tx.early_blocking to 1 in order
# to enable early blocking. The variable tx.early_blocking is set to 0 by
# default. Early blocking is thus disabled by default.
#
# Please note that early blocking will hide potential alerts from you. This
# means that a payload that would appear in an alert in phase 2 (or phase 4)
# does not get evaluated if the request is being blocked early. So when you
# disabled early blocking again at some point in the future, then new alerts
# from phase 2 might pop up.
#SecAction \
# "id:900120,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:tx.early_blocking=1"
#
# -- [[ HTTP Policy Settings ]] ------------------------------------------------
#
# This section defines your policies for the HTTP protocol, such as:
# - allowed HTTP versions, HTTP methods, allowed request Content-Types
# - forbidden file extensions (e.g. .bak, .sql) and request headers (e.g. Proxy)
#
# These variables are used in the following rule files:
# - REQUEST-911-METHOD-ENFORCEMENT.conf
# - REQUEST-920-PROTOCOL-ENFORCEMENT.conf
# HTTP methods that a client is allowed to use.
# Default: GET HEAD POST OPTIONS
# Example: for RESTful APIs, add the following methods: PUT PATCH DELETE
# Example: for WebDAV, add the following methods: CHECKOUT COPY DELETE LOCK
# MERGE MKACTIVITY MKCOL MOVE PROPFIND PROPPATCH PUT UNLOCK
# Uncomment this rule to change the default.
#SecAction \
# "id:900200,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'"
# Content-Types that a client is allowed to send in a request.
# Default: |application/x-www-form-urlencoded| |multipart/form-data| |multipart/related|
# |text/xml| |application/xml| |application/soap+xml| |application/x-amf| |application/json|
# |application/cloudevents+json| |application/cloudevents-batch+json| |application/octet-stream|
# |application/csp-report| |application/xss-auditor-report| |text/plain|
# Uncomment this rule to change the default.
#
# Please note, that the rule where CRS uses this variable (920420) evaluates it with operator
# `@within`, which is case sensitive, but uses t:lowercase. You must add your whole custom
# Content-Type with lowercase.
#
#SecAction \
# "id:900220,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |multipart/related| |text/xml| |application/xml| |application/soap+xml| |application/x-amf| |application/json| |application/cloudevents+json| |application/cloudevents-batch+json| |application/octet-stream| |application/csp-report| |application/xss-auditor-report| |text/plain|'"
# Allowed HTTP versions.
# Default: HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0
# Example for legacy clients: HTTP/0.9 HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0
# Note that some web server versions use 'HTTP/2', some 'HTTP/2.0', so
# we include both version strings by default.
# Uncomment this rule to change the default.
#SecAction \
# "id:900230,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:'tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0'"
# Forbidden file extensions.
# Guards against unintended exposure of development/configuration files.
# Default: .asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/
# Example: .bak/ .config/ .conf/ .db/ .ini/ .log/ .old/ .pass/ .pdb/ .rdb/ .sql/
# Uncomment this rule to change the default.
#SecAction \
# "id:900240,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:'tx.restricted_extensions=.asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/'"
# Forbidden request headers.
# Header names should be lowercase, enclosed by /slashes/ as delimiters.
# Blocking Proxy header prevents 'httpoxy' vulnerability: https://httpoxy.org
# Default: /proxy/ /lock-token/ /content-range/ /if/ /user-agentt/
# Uncomment this rule to change the default.
#SecAction \
# "id:900250,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:'tx.restricted_headers=/proxy/ /lock-token/ /content-range/ /if/ /user-agentt/'"
# Content-Types charsets that a client is allowed to send in a request.
# The content-types are enclosed by |pipes| as delimiters to guarantee exact matches.
# Default: |utf-8| |iso-8859-1| |iso-8859-15| |windows-1252|
# Uncomment this rule to change the default.
#SecAction \
# "id:900280,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:'tx.allowed_request_content_type_charset=|utf-8| |iso-8859-1| |iso-8859-15| |windows-1252|'"
#
# -- [[ HTTP Argument/Upload Limits ]] -----------------------------------------
#
# Here you can define optional limits on HTTP get/post parameters and uploads.
# This can help to prevent application specific DoS attacks.
#
# These values are checked in REQUEST-920-PROTOCOL-ENFORCEMENT.conf.
# Beware of blocking legitimate traffic when enabling these limits.
#
# Block request if number of arguments is too high
# Default: unlimited
# Example: 255
# Uncomment this rule to set a limit.
#SecAction \
# "id:900300,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:tx.max_num_args=255"
# Block request if the length of any argument name is too high
# Default: unlimited
# Example: 100
# Uncomment this rule to set a limit.
#SecAction \
# "id:900310,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:tx.arg_name_length=100"
# Block request if the length of any argument value is too high
# Default: unlimited
# Example: 400
# Uncomment this rule to set a limit.
#SecAction \
# "id:900320,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:tx.arg_length=400"
# Block request if the total length of all combined arguments is too high
# Default: unlimited
# Example: 64000
# Uncomment this rule to set a limit.
#SecAction \
# "id:900330,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:tx.total_arg_length=64000"
# Block request if the file size of any individual uploaded file is too high
# Default: unlimited
# Example: 1048576
# Uncomment this rule to set a limit.
#SecAction \
# "id:900340,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:tx.max_file_size=1048576"
# Block request if the total size of all combined uploaded files is too high
# Default: unlimited
# Example: 1048576
# Uncomment this rule to set a limit.
#SecAction \
# "id:900350,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:tx.combined_file_sizes=1048576"
#
# -- [[ Easing In / Sampling Percentage ]] -------------------------------------
#
# Adding the Core Rule Set to an existing productive site can lead to false
# positives, unexpected performance issues and other undesired side effects.
#
# It can be beneficial to test the water first by enabling the CRS for a
# limited number of requests only and then, when you have solved the issues (if
# any) and you have confidence in the setup, to raise the ratio of requests
# being sent into the ruleset.
#
# Adjust the percentage of requests that are funnelled into the Core Rules by
# setting TX.sampling_percentage below. The default is 100, meaning that every
# request gets checked by the CRS. The selection of requests, which are going
# to be checked, is based on a pseudo random number generated by ModSecurity.
#
# If a request is allowed to pass without being checked by the CRS, there is no
# entry in the audit log (for performance reasons), but an error log entry is
# written. If you want to disable the error log entry, then issue the
# following directive somewhere after the inclusion of the CRS
# (E.g., RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf).
#
# SecRuleUpdateActionById 901450 "nolog"
#
# ATTENTION: If this TX.sampling_percentage is below 100, then some of the
# requests will bypass the Core Rules completely and you lose the ability to
# protect your service with ModSecurity.
#
# Uncomment this rule to enable this feature:
#
#SecAction "id:900400,\
# phase:1,\
# pass,\
# nolog,\
# setvar:tx.sampling_percentage=100"
#
# -- [[ Check UTF-8 encoding ]] ------------------------------------------------
#
# The CRS can optionally check request contents for invalid UTF-8 encoding.
# We only want to apply this check if UTF-8 encoding is actually used by the
# site; otherwise it will result in false positives.
#
# Uncomment this rule to use this feature:
#
#SecAction \
# "id:900950,\
# phase:1,\
# nolog,\
# pass,\
# t:none,\
# setvar:tx.crs_validate_utf8_encoding=1"
#
# -- [[ Collection timeout ]] --------------------------------------------------
#
# Set the SecCollectionTimeout directive from the ModSecurity default (1 hour)
# to a lower setting which is appropriate to most sites.
# This increases performance by cleaning out stale collection (block) entries.
#
# This value should be greater than or equal to any block durations or timeouts
# set by plugins that make use of ModSecurity's persistent collections (e.g. the
# DoS protection and IP reputation plugins).
#
# Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#SecCollectionTimeout
# Please keep this directive uncommented.
# Default: 600 (10 minutes)
SecCollectionTimeout 600
#
# -- [[ End of setup ]] --------------------------------------------------------
#
# The CRS checks the tx.crs_setup_version variable to ensure that the setup
# has been loaded. If you are not planning to use this setup template,
# you must manually set the tx.crs_setup_version variable before including
# the CRS rules/* files.
#
# The variable is a numerical representation of the CRS version number.
# E.g., v3.0.0 is represented as 300.
#
SecAction \
"id:900990,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.crs_setup_version=400"
Include /usr/share/owasp-modsecurity-crs/rules/*.conf

View File

@ -6,6 +6,8 @@ error_log logs/error.log;
error_log logs/error.log notice;
error_log logs/error.log info;
load_module /usr/lib/nginx/modules/ngx_http_modsecurity_module.so;
events {
worker_connections 1024;
}
@ -31,7 +33,8 @@ http {
location / {
return 301 https://$host$request_uri;
}
}
include ../conf.d/*.conf;
include conf.d/*.conf;
}

View File

@ -1,13 +1,36 @@
---
- name: Install openresty
- name: Install components
become: yes
package:
name: "{{ item }}"
state: present
loop:
- openresty
- nginx
- libmodsecurity
- nginx-mod-modsecurity
- php
- php-fpm
- name: Config directories
become: yes
file:
path: "{{ item }}"
state: directory
owner: http
group: http
mode: 0750
loop:
- /usr/share/webapps/aninix
- /etc/nginx/conf
- /etc/nginx/conf.d
- /etc/modsecurity
- /var/log/modsec
- /var/log/modsec/tmp
- /var/log/modsec/data
- /var/log/modsec/audit
- /var/log/modsec/uploads
- name: Copy PHP config
become: yes
copy:
@ -17,26 +40,11 @@
group: root
mode: 0755
- name: Copy Webserver config
become: yes
copy:
src: webserver.service
dest: /usr/lib/systemd/system/webserver.service
owner: http
group: http
mode: 0660
register: servicefile
- systemd:
daemon_reload: true
when: servicefile.changed
become: yes
- name: Copy conf.d
become: yes
copy:
src: "conf.d/{{ inventory_hostname }}/"
dest: /opt/openresty/nginx/conf.d/
dest: /etc/nginx/conf.d/
owner: http
group: http
mode: 0660
@ -48,38 +56,102 @@
become: yes
copy:
src: conf/
dest: /opt/openresty/nginx/conf/
dest: /etc/nginx/conf/
owner: http
group: http
mode: 0660
follow: true
register: conf
- name: Copy conf
become: yes
copy:
src: apps/
dest: /usr/share/webapps/aninix
owner: http
group: http
mode: 0660
follow: true
- name: Nginx pidfile
become: yes
ignore_errors: true
file:
path: /run/nginx.pid
state: file
owner: http
group: http
mode: 0640
- name: Nginx log folder
become: yes
file:
path: /var/log/nginx
state: directory
owner: http
group: http
mode: 0750
- name: Populate security config
become: yes
template:
src: conf/sec.conf.j2
dest: /opt/openresty/nginx/conf/sec.conf
dest: /etc/nginx/conf/sec.conf
owner: http
group: http
mode: 0660
register: secconf
- name: Ensure default openresty service file is off.
- name: Clone OWASP-CRS
ignore_errors: true
become: yes
service:
name: openresty
state: stopped
enabled: no
git:
repo: https://github.com/coreruleset/coreruleset.git
update: yes
force: yes
single_branch: yes
dest: /usr/share/owasp-modsecurity-crs
umask: "0022"
- name: Modsecurity config
become: yes
register: modsecconf
copy:
dest: /etc/modsecurity/main.conf
src: modsec.conf
owner: http
group: http
mode: 0750
validate: /usr/bin/modsec-rules-check %s
- name: Modsecurity logrotate
become: yes
copy:
dest: /etc/logrotate.d/modsecurity
src: logrotate.modsec.conf
owner: root
group: root
mode: 0644
- name: Copy conf
become: yes
copy:
src: nginx.conf
dest: /etc/nginx/nginx.conf
owner: http
group: http
mode: 0660
follow: true
#validate: nginx -t -p /etc/nginx -c %s # Commented due to base pathing issues
register: baseconf
- name: Ensure service is started
become: yes
when: conf.changed or confd.changed or secconf.changed
when: conf.changed or confd.changed or secconf.changed or baseconf.changed or modsecconf.changed
service:
name: "{{ item }}"
enabled: yes
state: restarted
loop:
- php-fpm
- webserver
- nginx

View File

@ -11,12 +11,15 @@ ssl_prefer_server_ciphers on;
add_header "Strict-Transport-Security" "max-age=63072000; includeSubDomains; preload";
add_header "X-Content-Type-Options" "nosniff";
add_header "Public-Key-Pins" "pin-sha256=\"JYR9Zo608E/dQLErawdAxWfafQJDCOtsLJb+QdneIY0=\"; max-age=315360000; includeSubDomains";
add_header "Public-Key-Pins" "pin-sha256=\"sRHdihwgkaib1P1gxX8HFszlD+7/gTfNvuAybgLPNis=\"; pin-sha256=\"YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg=\"; pin-sha256=\"C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHFr8M=\"; max-age=60; includeSubDomains";
add_header "X-XSS-Protection" "1; mode=block";
add_header "X-Frame-Options" "SAMEORIGIN";
# Cross-Origin Resource Sharing
# add_header 'Access-Control-Allow-Origin' '*' always;
# add_header 'Access-Control-Allow_Credentials' 'true' always;
# add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range' always;
# add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH' always;
# ModSecurity WAF
modsecurity on;
modsecurity_rules_file /etc/modsecurity/main.conf;

View File

@ -1,3 +0,0 @@
search
/srv/wolfpack/search-results
aninix.net

View File

@ -1,4 +0,0 @@
download
/usr/local/src/isos/
wget -q -O - 'https://www.archlinux.org/download/' | grep rackspace | cut -f 2 -d \" | head -n 1
echo PREVRESULT/$(wget -q -O - PREVRESULT | grep x86_64.iso | head -n 1 | cut -f 2 -d \")

View File

@ -1,3 +0,0 @@
download
/usr/local/src/isos
curl -s https://centos.org/download/ | grep Minimal | grep 'a href' | cut -f 2 -d '"'

View File

@ -1,5 +0,0 @@
download
/srv/wolfpack/
curl -s https://portableapps.com/apps/internet/google_chrome_portable | tr '<' '\n' | tr '>' '\n' | tr \" '\n' | grep online.paf.exe | sed 's/ /\%20/g' | sed 's/\&/\\\&/g'
curl -s https://portableapps.comPREVRESULT | tr '"' '\n' | grep redirect | tail -n 1
echo https://portableapps.comPREVRESULT

View File

@ -1,11 +0,0 @@
shows
/srv/yggdrasil/new_acquisition
S06E11#Game of Thrones
S04E21#Vikings#
S02E13#Mr Robot#HDTV
S02E12#Marco Polo
S02E12#Criminal Minds Beyond Borders#
S02E14#Dark Matter#ettv
S03E22#Star Wars Rebels#
S02E11#Shadowhunters#
S03E18#Gotham#

View File

@ -1,8 +0,0 @@
torrent
/srv/yggdrasil/new_acquisition
King Arthur 2017 BRrip
The Great Wall 2017 BRrip
Edge of 17 2016 BRrip
Bilal: A New Breed of Hero 2015
John Wick Chapter 2 2017 HDrip
Fast 8 HDRip 2017

View File

@ -1,3 +0,0 @@
download
/usr/local/src/isos/
elinks --dump https://www.offensive-security.com/kali-linux-arm-images/ | grep rpi | head -n 1 | sed 's/^\s\+//'

View File

@ -1,4 +0,0 @@
download
/usr/local/src/isos/
wget -q -O - http://cdimage.kali.org/current/ | grep amd64.iso | head -n 1 | cut -f 8 -d '"'
echo http://cdimage.kali.org/current/PREVRESULT

View File

@ -1,12 +0,0 @@
shows
/srv/yggdrasil/new_acquisition
S06E23#2 Broke Girls#
S10E25#Big Bang Theory#
S04E21#The Fosters#
S18E19#Law Order SVU#
S08E23#The Middle#
S08E22#Modern Family#
S07E13#Shameless US
S07E17#The Walking Dead#
S03E25#Scorpion#
S05E05#Prison Break#ettv

View File

@ -1,4 +0,0 @@
download
/var/cache/localpkg/
wget -q -O - https://www.mediawiki.org/wiki/Download | grep 'Download MediaWiki' | cut -f 6 -d \"
echo https:PREVRESULT

View File

@ -1,3 +0,0 @@
download
/usr/local/src/isos/
wget -q -O - https://www.plop.at/en/bootmanager/download.html | grep 'plpbt-' | head -n 2 | tail -n 1 | cut -f 3 -d '=' | cut -f 1 -d ' '

View File

@ -1,3 +0,0 @@
download
/srv/wolfpack/
echo http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe

View File

@ -1,4 +0,0 @@
download
/usr/local/src/isos/
wget -q -O - 'https://www.raspberrypi.org/downloads/raspbian/' | grep 'btn dl-zip' | grep -i lite | cut -f 2 -d \"
curl -sI PREVRESULT | grep Location: | cut -f 2 -d ' ' | sed 's/\r//g'

View File

@ -1,3 +0,0 @@
download
/srv/wolfpack/
wget -q -O - http://portableapps.com/apps/internet/winscp_portable | grep 'sf-download' | cut -f 4 -d \" | head -n 1

View File

@ -1,3 +1,3 @@
search
/srv/wolfpack/
Riffle
aninix.net

View File

@ -0,0 +1,4 @@
download
/srv/wolfpack
curl -s 'https://mirror.rackspace.com/archlinux/iso/latest/' | grep -m 1 x86_64.iso | cut -f 2 -d \"
echo https://mirror.rackspace.com/archlinux/iso/latest/PREVRESULT

View File

@ -1,4 +1,4 @@
search
/srv/wolfpack/search-results
/srv/wolfpack
Eminem Shows
Eminem Concerts

View File

@ -0,0 +1,4 @@
download
/srv/wolfpack
curl -s http://cdimage.kali.org/current/ | grep -m 1 live-amd64.iso | cut -f 4 -d '"'
echo http://cdimage.kali.org/current/PREVRESULT

View File

@ -0,0 +1,3 @@
download
/srv/wolfpack
echo https://downloads.raspberrypi.org/imager/imager_latest.exe

View File

@ -3,14 +3,39 @@
- name: Packages
become: yes
package:
state: present
name:
- wolfpack
- WolfPack
- name: Config
- name: File config
become: yes
copy:
src: "{{ inventory_hostname }}"
when: "wolfpack_config is not defined"
ansible.posix.synchronize:
src: "{{ inventory_hostname }}/"
dest: /usr/local/etc/WolfPack
delete: true
- name: Git config
become: yes
when: "wolfpack_config is defined"
git:
repo: "{{ wolfpack_config }}"
dest: /usr/local/etc/WolfPack
clone: yes
update: no
- name: Hardening
become: yes
loop:
- /usr/local/etc/WolfPack
- /srv/wolfpack
file:
path: "{{ item }}"
state: directory
owner: wolfpack
group: wolfpack
mode: 0755
recurse: true
- name: Timer
become: yes
@ -19,7 +44,3 @@
state: started
enabled: yes
daemon_reload: yes
# TODO Add sshfs and mountpoint for Darknet
# TODO Add config folders and restart daemon on change
# TODO Deprecate offload-wolfpack for Deluge move to sshfs

View File

@ -0,0 +1,13 @@
---
- name: AMD Ucode
become: yes
register: amd_ucode
package:
name: amd-ucode
state: present
- name: Rebuild grub
become: yes
when: amd_ucode.changed
command: grub-mkconfig -o /boot/grub/grub.cfg

View File

@ -0,0 +1,14 @@
---
- name: Install software
become: yes
package:
name: powerpanel
state: present
- name: Start service
become: yes
service:
name: pwrstatd.service
state: started
enabled: yes

View File

@ -0,0 +1,13 @@
---
- name: Intel Ucode
become: yes
register: intel_ucode
package:
name: intel-ucode
state: present
- name: Rebuild grub
become: yes
when: intel_ucode.changed
command: grub-mkconfig -o /boot/grub/grub.cfg

View File

@ -6,7 +6,6 @@
name:
- smartmontools
- hdparm
- apcupsd
state: present
- name: Set udev settings for drives
@ -31,4 +30,15 @@
when: udev_iosched.changed
- include_tasks: amd.yml
when: "'AMD' in ansible_processor[1]"
- include_tasks: intel.yml
when: "'Intel' in ansible_processor"
- include_tasks: cyberpower.yml
when: "ups == 'cyberpower'"
- include_tasks: aps.yml
when: "ups == 'aps'"