Compare commits

...

24 Commits

Author SHA1 Message Date
DarkFeather 9366d8b6d7
Catch up for Foundation 2024-04-05 13:16:42 -05:00
DarkFeather 5c3eb7f358
Moving VMs to Host cpu emulation 2024-04-04 13:15:38 -05:00
DarkFeather 33cf371a0d
Updating roles 2024-04-01 00:53:08 -05:00
DarkFeather 9aa0a89b79
Seeding Aether 2024-04-01 00:52:29 -05:00
DarkFeather 3a01543c8b
Capturing APC automation 2024-04-01 00:49:36 -05:00
DarkFeather 87973dfb6e
Simplifying group management 2024-04-01 00:49:02 -05:00
DarkFeather 85286b5412
Catching up with automation 2024-04-01 00:47:05 -05:00
DarkFeather 6f36d515e3
AniNIX/Wiki#21 -- effecting renames for policy 2024-04-01 00:44:23 -05:00
DarkFeather 323b4dd306
Pathing updates for Gitea 1.21.5 -- custom/public to custom/public/assets 2024-03-07 12:28:46 -06:00
DarkFeather e75d03a313
Update for automated response around poorly behaving archlinux-keyring weekly timer; rename Sora role to Password 2024-03-07 12:27:21 -06:00
DarkFeather 930441ae9a
Adding enforcement exit code 2024-01-18 12:04:30 -06:00
DarkFeather f9a3bd789b
Removing duplicate resource 2024-01-12 16:17:55 -06:00
DarkFeather 15dd844093
Correcting abandoned rename 2024-01-12 16:10:40 -06:00
DarkFeather 43d7375dae
Updating AniNIX/Scratch for naming & persistence warning 2024-01-12 15:34:41 -06:00
DarkFeather cd3210c5fb
Adding minor webapps to WebServer tracking 2024-01-12 13:06:58 -06:00
DarkFeather 221ce69a80
Catching up wolfpack to reenable 2024-01-12 13:06:19 -06:00
DarkFeather 1ca0272031
Adding ucode & UPS definitions to IAC 2023-12-21 12:58:32 -06:00
DarkFeather e244895552
Finalizing Cyberbrain role 2023-12-19 16:20:58 -06:00
DarkFeather cea66f285a
Finishing rename from Core to Yggdrasil 2023-12-19 16:16:35 -06:00
DarkFeather 50167c0f03
Virtualizing Core host as Yggdrasil VM 2023-12-07 13:28:54 -06:00
DarkFeather 7b98c953b1
Merging out nginx conversion 2023-11-30 02:48:50 -06:00
DarkFeather 528af8b0f5
Fixing PKGBUILD dependencies 2023-11-16 12:58:52 -06:00
DarkFeather 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
DarkFeather 5fa67890c2
Moving from openresty to nginx+modsec for HTTP/2 Rapid Reset reasons 2023-11-09 13:03:06 -06:00
159 changed files with 2699 additions and 979 deletions

6
.gitignore vendored
View File

@ -1,12 +1,14 @@
# Generated files
roles/Node/files/*-vm.service
roles/Nazara/files/dns
roles/Nazara/files/dhcp
roles/Chappaai/files/dns
roles/Chappaai/files/dhcp
roles/Node/files/vm-definitions/**
roles/ShadowArch/files/mirrorlist
roles/Sharingan/files/monit/checks/availability
roles/Foundation/files/custom/public/img/**
roles/Maat/files/pacoloco.yaml
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,10 +1,10 @@
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
It is named after the fictional Star Wars Imperial Intelligence organization that oversaw the various divisions of Intelligence and orchestrated their operations. Like its namesake, this project oversees the various tools within our ecosystem and enforces compliance with standards.
It is named after flagship carrier Kapisi from the game [Homeworld: Deserts of Kharak](https://store.steampowered.com/app/281610?snr=5000_5100___primarylinks). The carrier was the command and production center of Operation Khadiim, an expedition to understand an anomaly on their world & escape the fanaticism of their Gaalsien rivals. The S'jet were able to succeed in this mission not only due to the military efficacy of their forces but also through the research and production capabilities available to the Kapisi.
This project seeks to give other admins and engineers to launch their own infrastructures and break out of any strangleholds that may have entangled them, whether that is tribalism, vendor lock, or stigma.
# Relevant Files and Software
@ -14,7 +14,7 @@ export ANSIBLE_VAULT_PASSWORD_FILE=$HOME/password-store/${organization}.vault.pa
export ANSIBLE_VAULT_FILE=$HOME/password-store/${organization}.vault
```
Take a look at `examples/msn0.yml` as an example inventory -- make sure you populate one of your own.
Take a look at `examples/msn0.yml` as an example inventory -- make sure you populate one of your own. The scripts here expect inventories to have layers of groups -- the top group under `all` must be managed vs. unmanaged. The rest of the scripts use YAMLPath to sort out the rest of the groups.
Once you have your vault and inventory, use [AniNIX/ShadowArch](/AniNIX/ShadowArch) with your hypervisor to provision the base image for your machines, or [Raspbian](https://www.raspberrypi.org/).
@ -30,14 +30,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

@ -11,6 +11,7 @@
import os
import subprocess
import sys
import re
import yaml
rolepath='../roles/Sharingan/files'

View File

@ -1,51 +1,46 @@
#!/usr/bin/env python3
# File: generate-pihole-dns-dhcp.py
#
#
# Description: This file generates the DNS and DHCP files for pihole.
#
# It expects that the inventory has two levels of grouping.
#
# Package: AniNIX/Ubiqtorate
# Copyright: WTFPL
#
#
# Author: DarkFeather <darkfeather@aninix.net>
import os
import re
import subprocess
import sys
import yaml
from kapisi_lib import *
rolepath='../roles/Nazara/files'
rolepath='../roles/Chappaai/files'
dnsfilepath=rolepath+"/dns"
dhcpfilepath=rolepath+"/dhcp"
entryset={}
def WriteDHCPEntry(content,hosttype,hostclass):
def WriteDHCPEntries(replica_domain,dhcpfile):
### Create the DHCP entry
# param content: the yaml content to parse
# param hosttype: managed or unmanaged
# param hostclass: the type of host as classified in the yaml
global dhcpfile
global entryset
for host in entryset:
# Entries should be:
# dhcp-host=mac,ip,fqdn
dhcpfile.write('dhcp-host=' + entryset[host][1] + ',' + entryset[host][0] + ',' + host + '.' + replica_domain + '\n')
with open(dhcpfilepath,'a') as dhcpfile:
for host in content['all']['children'][hosttype]['children'][hostclass]['hosts']:
try:
dhcpfile.write('dhcp-host=' + content['all']['children'][hosttype]['children'][hostclass]['hosts'][host]['mac'] + ',' + content['all']['children'][hosttype]['children'][hostclass]['hosts'][host]['ip'] + ',' + host + '.' + content['all']['vars']['replica_domain'] + '\n')
except:
print(host + ' is not complete for DHCP.')
def WriteDNSEntry(content,hosttype,hostclass):
def WriteDNSEntries(replica_domain,dnsfile):
### Create the DNS entry
# param content: the yaml content to parse
# param hosttype: managed or unmanaged
# param hostclass: the type of host as classified in the yaml
global dnsfile
with open(dnsfilepath,'a') as dnsfile:
# Write host entries
for host in content['all']['children'][hosttype]['children'][hostclass]['hosts']:
try:
dnsfile.write(content['all']['children'][hosttype]['children'][hostclass]['hosts'][host]['ip'] + ' ' + host + '.' + content['all']['vars']['replica_domain'] + ' ' + host + '\n')
except:
print(host + ' is not complete for DNS.')
global entryset
for host in entryset:
# Entries should be:
# ip host fqdn
dnsfile.write(entryset[host][0] + ' ' + host + '.' + replica_domain + ' ' + host + '\n')
def GenerateFiles(file):
### Open the file and parse it
@ -58,29 +53,30 @@ def GenerateFiles(file):
# Parse the yaml
with open(file, 'r') as stream:
content = yaml.safe_load(stream)
replica_domain = content['all']['vars']['replica_domain']
external_domain = content['all']['vars']['external_domain']
# Clear the DNS file
with open(dhcpfilepath,'w') as dhcpfile:
dhcpfile.write('dhcp-range='+content['all']['vars']['dhcprange']+'\n')
dhcpfile.write('dhcp-option=option:dns-server,'+content['all']['vars']['dns']+'\n\n')
dhcpfile.write('dhcp-range='+content['all']['vars']['staticrange']+'\n')
WriteDHCPEntries(replica_domain,dhcpfile)
with open(dnsfilepath,'w') as dnsfile:
vips=subprocess.run(["/bin/bash", "-c", "echo | openssl s_client -connect "+content['all']['vars']['external_domain']+":443 | openssl x509 -text -noout | grep DNS: | tr ',' '\n' | sed 's/\s\+DNS://' | grep -ivE ^"+content['all']['vars']['external_domain']+" | tr '\n' ' '"], capture_output=True).stdout.decode("utf-8")
dnsfile.write(content['all']['vars']['webfront']+' '+content['all']['vars']['external_domain']+' '+vips+"\n")
# Add DNS entries for each host
hosttype = 'managed'
for hostclass in ['physical','virtual','geth_hubs']:
WriteDNSEntry(content,hosttype,hostclass)
WriteDHCPEntry(content,hosttype,hostclass)
hosttype = 'unmanaged'
for hostclass in ['ovas','test_ovas','appliances','adhoc_appliances','iot']:
WriteDNSEntry(content,hosttype,hostclass)
WriteDHCPEntry(content,hosttype,hostclass)
dnsfile.write(content['all']['vars']['webfront']+' '+external_domain+' '+content['all']['vars']['external_subdomains'].replace(' ','.'+external_domain+' ')+'.'+external_domain+' '+content['all']['vars']['hosted_domains']+"\n")
WriteDNSEntries(replica_domain,dnsfile)
print('Files should be in '+rolepath);
### Main function
# param sys.argv: Input arguments
if __name__ == '__main__':
if len(sys.argv) != 2:
if len(sys.argv) < 2:
print("You need to supply an inventory file.")
sys.exit(1)
if len(sys.argv) == 3:
entryset = TrackIPEntries(sys.argv[1],sys.argv[2])
else:
entryset = TrackIPEntries(sys.argv[1])
GenerateFiles(sys.argv[1])
#dumper.dump(entryset)
sys.exit(0)

View File

@ -1,6 +1,6 @@
#!/bin/bash
# File: gen-ssh-keyscan
# File: ./generate-ssh-keyscan
#
# Description: This file generates a known_host block for the inventory.
#

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
@ -54,7 +54,7 @@ def WriteVMFile(content,hosttype,hostclass):
vmfile.write('[Service]\n')
vmfile.write('ExecStart=/usr/sbin/qemu-system-x86_64 -name AniNIX/' + host + ' -machine type=pc,accel=kvm')
if 'uefi' in content['all']['children'][hosttype]['children'][hostclass]['hosts'][host].keys(): vmfile.write(' -bios /usr/share/edk2-ovmf/x64/OVMF.fd')
vmfile.write(' -cpu qemu64 -smp ' + cores + ' ' + disks + ' -net nic,macaddr=' + mac + ',model=virtio -net bridge,br=' + bridge + ' -vga std -nographic -vnc :' + str(vnc) + ' -m size=' + str(memory) + 'G -device virtio-rng-pci\n')
vmfile.write(' -cpu host -smp ' + cores + ' ' + disks + ' -net nic,macaddr=' + mac + ',model=virtio -net bridge,br=' + bridge + ' -vga std -nographic -vnc :' + str(vnc) + ' -m size=' + str(memory) + 'G -device virtio-rng-pci\n')
vmfile.write('ExecReload=/bin/kill -HUP $MAINPID\n')
vmfile.write('KillMode=process\n')
vmfile.write('Restart=always\n')
@ -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__':

63
bin/kapisi_lib.py Normal file
View File

@ -0,0 +1,63 @@
import re
import yaml
from types import SimpleNamespace
from yamlpath.common import Parsers
from yamlpath.wrappers import ConsolePrinter
from yamlpath import Processor
from yamlpath import YAMLPath
from yamlpath.exceptions import YAMLPathException
def TrackIPEntries(yaml_file,searchstring='all.children.**.ip'):
### Try to parse an Ansible inventory for hosts with the 'ip' attribute.
# param file: the file to parse
# return: a populated entry set in form [{Host,[ip,mac]},...]
# Borrowing from upstream author's example at https://pypi.org/project/yamlpath/
entryset = {}
# The various classes of this library must be able to write messages somewhere
# when things go bad.
#logging_args = SimpleNamespace(quiet=True, verbose=False, debug=False)
logging_args = SimpleNamespace(quiet=True, verbose=True, debug=True)
log = ConsolePrinter(logging_args)
# Prep the YAML parser
yaml = Parsers.get_yaml_editor()
(yaml_data, doc_loaded) = Parsers.get_yaml_data(yaml, log, yaml_file)
if not doc_loaded:
exit(1)
processor = Processor(log, yaml_data)
yaml_path = YAMLPath(searchstring)
# Create a regex pattern to remove the end of the path
ippattern = re.compile('\.ip$')
try:
for node_coordinate in processor.get_nodes(yaml_path, mustexist=True):
# Strip the path to the host entry.
path = ippattern.sub("",str(node_coordinate.path))
# Pull the IP
ip = str(node_coordinate.node)
# Pull the hosname
splitpath = path.split('.')
hostname = splitpath[len(splitpath)-1]
#print("Got {} from '{}''.".format(ip,path))
# Path the MAC
mac_yaml_path = YAMLPath(path+".mac")
mac=""
try:
for node_coordinate in processor.get_nodes(mac_yaml_path, mustexist=True):
mac = str(node_coordinate.node)
except YAMLPathException as ex:
log.error(ex)
# Add the host to the entryset.
entryset.update({ hostname : [ip,mac] })
except YAMLPathException as ex:
log.error(ex)
finally:
return entryset

View File

@ -17,11 +17,11 @@ group=all
offset=0
unset inventory
function usage() {
function usage() {
# Show helptext
# param retcode: what to exit
retcode="$1"
echo "Usage: $0 [ -o offset ] [-g group ] -i inventory.yml"
echo "Usage: $0 [ -o offset ] [-g group ] [-i inventory.yml]"
echo " $0 -h"
echo "Group is optional -- add it if you only want to look at a specific subset."
echo "Add -v for verbosity."
@ -41,7 +41,7 @@ function tmuxHosts() {
name="$group-$offset"
# If no TMUX session started, then add one with four panes.
if [ -z "$TMUX" ]; then
if [ -z "$TMUX" ]; then
tmux new-session -s "$name" -d "/bin/bash -l -c ssh\\ $host1"
tmux select-window -t "$name":0
tmux split-window "/bin/bash -l -c ssh\\ $host2"
@ -51,7 +51,7 @@ function tmuxHosts() {
tmux setw synchronize-panes
tmux a -d -t "$name"
# Otherwise, add a new window to the current session with all four sessions.
else
else
tmux new-window -n "$name" "/bin/bash -l -c ssh\\ $host1"
tmux select-window -t "$name"
tmux split-window "/bin/bash -l -c ssh\\ $host2"
@ -76,12 +76,11 @@ if [ "$(basename $0)" == "tmux-hosts" ]; then
*) usage 1 ;;
esac
done
if [ -z "$inventory" ]; then
echo Need an inventory.
usage 2;
inventory=$(grep -E ^inventory ~/.ansible.cfg | cut -f 2 -d '=')
fi
tmuxHosts $(ansible -i "$inventory" --list-hosts "$group"\
| grep -v hosts\ \( \
| sed 's/\s\+//g' \

View File

@ -1,7 +1,9 @@
all:
vars:
# Environment-wide data
external_domain: aninix.net
external_domain: "aninix.net"
external_subdomains: "cyberbrain foundation irc lykos maat password sharingan singularity superintendent www yggdrasil"
hosted_domains: "travelpawscvt.com"
replica_domain: "MSN0.AniNIX.net"
time_zone: "America/Chicago"
# Services used by all
@ -19,7 +21,7 @@ all:
ansible_become_method: sudo
ansible_become_user: root
static: false
wireless_ssid: 'Shadowfeed'
wireless_ssid: 'Shadownet'
ansible_python_interpreter: auto_silent
ldap:
server: "10.0.1.3"
@ -32,47 +34,79 @@ all:
displayname: 'AniNIX'
gpgkey: '904DE6275579CB589D85720C1CC1E3F4ED06F296'
ssl: # Standard SSL cryptographic standards
identity: 'aninix.net-0001' # The Let's Encrypt identity to use
identity: 'aninix.net-0002' # The Let's Encrypt identity to use
ciphersuite: "!NULL:!SSLv2:!SSLv3:!TLSv1:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"
children:
managed:
children:
physical: # 10.0.1.0/28
hosts:
Nazara:
Chappaai:
ipinterface: eth0
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
Maker:
ipinterface: eth0
ip: 10.0.1.14
mac: B8:27:EB:B6:AA:0D
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
ip: 10.0.1.5
mac: B0:41:6F:0D:47:E1
tap: true
Node2:
ipinterface: enp1s0f0
ip: 10.0.1.7
mac: B0:41:6F:0D:41:D1
tap: true
Node3:
ipinterface: enp1s0f0
ip: 10.0.1.8
mac: B0:41:6F:0D:51:0E
tap: true
children:
Node:
hosts:
Node1:
ipinterface: enp1s0
ip: 10.0.1.5
mac: FA:EC:43:87:4D:2D
tap: true
ups: 'aps'
active_vms:
- Yggdrasil
Node2:
ipinterface: enp1s0
ip: 10.0.1.7
mac: 56:02:ef:2c:1f:7c
tap: true
active_vms:
- DarkNet
- Maat
- Sharingan
- Superintendent
Node3:
ipinterface: enp1s0
ip: 10.0.1.8
mac: B2:C6:2C:02:B2:6E
tap: true
active_vms:
- TDS-Jump
Geth:
hosts:
Geth0:
ipinterface: eth0
ip: 10.0.1.9
mac: 84:16:F9:14:15:C5
static: true
k3s_primary: true
Geth1:
ipinterface: eth0
ip: 10.0.1.10
mac: E4:5F:01:01:FF:9C
static: true
Geth2:
ipinterface: eth0
ip: 10.0.1.11
mac: E4:5F:01:01:FF:D5
static: true
Geth3:
ipinterface: eth0
ip: 10.0.1.12
mac: E4:5F:01:01:FF:96
static: true
Geth4:
ipinterface: eth0
ip: 10.0.1.13
mac: E4:5F:01:01:FF:E4
static: true
virtual: # 10.0.1.16/28
vars:
hosts:
@ -87,18 +121,20 @@ 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:
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:
ip: 10.0.1.18
ipinterface: ens3
@ -106,26 +142,45 @@ all:
cores: 2
memory: 2
bridge: br0
vscan_enabled: true
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:
ipinterface: ens3
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
vscan_enabled: true
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
hosts:
Geth-Hub-1:
Vergil1:
ip: 10.0.1.32
mac: 84:16:F9:14:15:C5
mac: b8:27:eb:9a:73:dd
rotate: 0
remote: NS-RC4NA-14
Geth-Hub-2:
Vergil2:
ip: 10.0.1.33
mac: 84:16:F9:13:B6:E6
motion_enabled: no
rotate: 180
remote: NS-RC4NA-14
Geth-Hub-3:
Vergil3:
ip: 10.0.1.34
mac: b8:27:eb:60:73:68
rotate: 90
@ -135,7 +190,7 @@ all:
# Both OVA groups are in the same subnet -- test_ovas aren't monitored
ovas: # 10.0.1.48/28
hosts:
Geth:
Superintendent:
ip: 10.0.1.49
mac: DE:8B:9E:19:55:1E
cores: 2
@ -144,7 +199,7 @@ 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:
@ -155,7 +210,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=/srv/node/vm/TDSJump.qcow2'
DedNet:
ip: 10.0.1.50
mac: 00:15:5d:01:02:09
@ -164,7 +219,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 +240,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 +250,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,11 +260,11 @@ 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
Shadowfeed: # Router must be at root
Shadownet: # Router must be at root
ip: 10.0.1.1
mac: 2c:30:33:64:f4:03
Print: # Print is excepted for legacy setup reasons before we laid out subnets.
@ -218,21 +273,21 @@ 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:
ip: 10.0.1.64
mac: D0:40:EF:D4:14:CF
mac: f4:2b:8c:10:31:44
Lykos:
ip: 10.0.1.65
mac: 70:74:14:4F:8E:42
Games:
Node0:
ip: 10.0.1.66
mac: E0:BE:03:77:0E:88
LivingRoomTV:
@ -244,24 +299,25 @@ all:
TrainingRoomTV:
ip: 10.0.1.71
mac: 80:D2:1D:17:63:10
Tachikoma:
BT:
ip: 10.0.1.72
mac: 90:0f:0c:1a:d3:23
Dedsec:
mac: 8A:00:AA:7F:DF:D1
DedSec:
ip: 10.0.1.73
mac: 34:F6:4B:36:12:8F
# dhcp build space: 10.0.1.224/27
iot: # 10.0.2.0/24
hosts:
LinKeuei:
LivingRoomRegulator:
ip: 10.0.2.2
mac: 64:16:66:08:57:F5
Canary:
Monitor:
ip: 10.0.2.3
mac: 18:B4:30:2F:F1:37
Charon:
Gatekeeper:
ip: 10.0.2.4
mac: 64:52:99:14:28:2B
Skitarii-1:
# CaretakerAlpha has no network
CaretakerBravo:
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

@ -9,36 +9,23 @@
# Patch then restart a node
#
#
- hosts: physical,virtual
order: sorted
serial: 4
vars:
ansible_become: yes
ansible_become_method: sudo
tasks:
- package:
name: archlinux-keyring
state: latest
- hosts: virtual,geth-hubs
- hosts: "{{ targets | default('virtual') }}"
order: sorted
serial: 4
vars:
ansible_become: yes
ansible_become_method: sudo
vars_files:
- "{{ lookup('env', 'ANSIBLE_VAULT_FILE') }}"
roles:
- patching
- hosts: physical
order: sorted
ignore_unreachable: true
serial: 4
vars:
ansible_become: yes
ansible_become_method: sudo
vars_files:
- "{{ lookup('env', 'ANSIBLE_VAULT_FILE') }}"
roles:
- patching
tasks:
- include_role:
name: patching
when: targets is unset

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

7
roles/Aether/README.md Normal file
View File

@ -0,0 +1,7 @@
See [AniNIX/Aether](/AniNIX/Aether) for complete details of the tool.
Role requirements:
* `secrets['Aether']` in Vault
* A YAML list of nodes under the key `Aether_nodes` in Vault
* A host called 'Core' to act as the source
* 22/tcp/sftp access through firewalls to the Core host from any clients

View File

@ -0,0 +1,3 @@
#!/bin/bash
### Gitea ###
tar cvzf "$BACKUPDIR"/gitea.tgz /var/lib/gitea/data

View File

@ -0,0 +1,3 @@
#!/bin/bash
### Grimoire ###
sudo -u postgres pg_dumpall > "$BACKUPDIR"/grimoire.sql

View File

@ -0,0 +1,3 @@
#!/bin/bash
### IRC Services ###
cp /opt/anope/data/anope.db "$BACKUPDIR"

View File

@ -0,0 +1,9 @@
#!/bin/bash
### Wiki ###
mkdir "$BACKUPDIR"/wiki/
for i in `find /usr/share/webapps/ -maxdepth 1 -type d | grep mediawiki`; do
foldername="$(echo "$i" | rev | cut -f 1 -d '/' | rev)"
dbname="$(grep '^\$wgDBname' "$i"/LocalSettings.php | cut -f 2 -d \")"
$BACKUPCMD "${i}"/LocalSettings.php "$BACKUPDIR"/wiki/"$foldername"-localsettings.php
sudo -u postgres pg_dump "$dbname" > "$BACKUPDIR"/wiki/"$dbname".psql
done

View File

@ -0,0 +1,3 @@
#!/bin/bash
### Yggdrasil -- File & SHA list only for space reasons ###
cp /srv/yggdrasil/library.sha256 "$BACKUPDIR"/yggdrasil.library.sha256

View File

@ -0,0 +1,146 @@
# Example configuration file for AIDE.
# More information about configuration options available in the aide.conf manpage.
@@define DBDIR /var/lib/aide
@@define LOGDIR /var/log/aide
# The location of the database to be read.
database_in=file:@@{DBDIR}/aide.db.gz
# The location of the database to be written.
#database_out=sql:host:port:database:login_name:passwd:table
#database_out=file:aide.db.new
database_out=file:@@{DBDIR}/aide.db.new.gz
# Whether to gzip the output to database
gzip_dbout=yes
# Default.
log_level=warning
report_level=changed_attributes
report_url=file:@@{LOGDIR}/aide.log
report_url=stdout
#report_url=stderr
#
# Here are all the attributes we can check
#p: permissions
#i: inode
#n: number of links
#l: link name
#u: user
#g: group
#s: size
###b: block count
#m: mtime
#a: atime
#c: ctime
#S: check for growing size
#I: ignore changed filename
#ANF: allow new files
#ARF: allow removed files
#
# Here are all the digests we can use
#md5: md5 checksum
#sha1: sha1 checksum
#sha256: sha256 checksum
#sha512: sha512 checksum
#rmd160: rmd160 checksum
#tiger: tiger checksum
#haval: haval checksum
#crc32: crc32 checksum
#gost: gost checksum
#whirlpool: whirlpool checksum
# These are the default rules
#R: p+i+l+n+u+g+s+m+c+md5
#L: p+i+l+n+u+g
#E: Empty group
#>: Growing logfile p+l+u+g+i+n+S
# You can create custom rules - my home made rule definition goes like this
ALLXTRAHASHES = sha1+rmd160+sha256+sha512+whirlpool+tiger+haval+gost+crc32
ALLXTRAHASHES = sha1+rmd160+sha256+sha512+tiger
# Everything but access time (Ie. all changes)
EVERYTHING = R+ALLXTRAHASHES
# Sane, with multiple hashes
# NORMAL = R+rmd160+sha256+whirlpool
NORMAL = R+rmd160+sha256
# For directories, don't bother doing hashes
DIR = p+i+n+u+g+acl+xattrs
# Access control only
PERMS = p+i+u+g+acl
# Logfile are special, in that they often change
LOG = >
# Just do md5 and sha256 hashes
LSPP = R+sha256
# Some files get updated automatically, so the inode/ctime/mtime change
# but we want to know when the data inside them changes
DATAONLY = p+n+u+g+s+acl+xattrs+md5+sha256+rmd160+tiger
# Next decide what directories/files you want in the database.
/boot NORMAL
/bin NORMAL
/sbin NORMAL
/lib NORMAL
/lib64 NORMAL
/opt NORMAL
/usr NORMAL
/root NORMAL
# These are too volatile
!/usr/src
!/usr/tmp
# Check only permissions, inode, user and group for /etc, but
# cover some important files closely.
/etc PERMS
!/etc/mtab
# Ignore backup files
!/etc/.*~
/etc/exports NORMAL
/etc/fstab NORMAL
/etc/passwd NORMAL
/etc/group NORMAL
/etc/gshadow NORMAL
/etc/shadow NORMAL
/etc/security/opasswd NORMAL
/etc/hosts.allow NORMAL
/etc/hosts.deny NORMAL
/etc/sudoers NORMAL
/etc/skel NORMAL
/etc/logrotate.d NORMAL
/etc/resolv.conf DATAONLY
/etc/nscd.conf NORMAL
/etc/securetty NORMAL
# Shell/X starting files
/etc/profile NORMAL
/etc/bashrc NORMAL
/etc/bash_completion.d/ NORMAL
/etc/login.defs NORMAL
/etc/zprofile NORMAL
/etc/zshrc NORMAL
/etc/zlogin NORMAL
/etc/zlogout NORMAL
/etc/profile.d/ NORMAL
/etc/X11/ NORMAL
# Ignore logs
!/var/lib/pacman/.*
!/var/cache/.*
!/var/log/.*
!/var/run/.*
!/var/spool/.*

View File

@ -0,0 +1,27 @@
---
- name: Copy the key
become: true
copy:
dest: /home/aether/.ssh/aether
content: "{{ aether_key.stdout }}"
- name: Copy the public key
become: true
copy:
dest: /home/aether/.ssh/aether.pub
content: "{{ aether_key.stdout }}"
- name: Enable the service
become: yes
service:
name: aether.timer
state: enabled
running: yes
- name: Enable the service - 2
become: yes
service:
name: aether-gen.timer
state: disabled
running: no

View File

@ -0,0 +1,64 @@
---
- name: Install the package
become: true
ignore_errors: true
package:
name: Aether
state: present
- name: Validate the user
vars:
service_account: aether
include_tasks: ../roles/common/service_account.yml
- name: Ensure the Aether identity is protected.
become: true
file:
path: "{{ item }}"
state: directory
owner: aether
group: aether
mode: 0700
loop:
- /home/aether/.ssh
- /usr/local/etc/Aether
- /usr/local/etc/Aether/backup-entries
- /usr/local/backup
- name: Ensure the Aether identity exists
delegate_to: Core # Core will track the identity that will then be shared to everyone else.
become: true
command:
creates: /home/aether/.ssh/aether
chdir: /home/aether/.ssh/
cmd: ssh-keygen -t ed25519 -N "" -f ./aether
- name: Read the Aether identity
become: true
delegate_to: Core
command: cat /home/aether/.ssh/aether
register: aether_key
- name: Read the Aether public identity
become: true
delegate_to: Core
command: cat /home/aether/.ssh/aether.pub
register: aether_pubkey
- include_tasks: source.yml
when: "{{ inventory_hostname }} is 'Core'"
- include_tasks: client.yml
when: "{{ inventory_hostname }} is 'Core'"
- name: Ensure the Aether identity files are protected.
become: true
file:
path: "{{ item }}"
owner: aether
group: aether
mode: 0600
loop:
- /home/aether/.ssh/aether
- /home/aether/.ssh/aether.pub

View File

@ -0,0 +1,42 @@
---
- name: Copy the backup scripts
become: yes
copy:
src: "backup-entries/{{ inventory_hostname }}"
dest: "/usr/local/etc/Aether/backup-entries"
owner: aether
group: aether
- name: Seed the backup passphrase
become: yes
copy:
content: "{{ passwords['Aether'] }}"
dest: "/usr/local/etc/Aether/pass.txt"
owner: aether
group: aether
mode: 0600
- name: Enable the generation service
become: yes
when: "{{ inventory_hostname }} == 'Core'"
service:
name: aether-gen.timer
state: enabled
running: yes
- name: Enable the generation service - 2
become: yes
when: "{{ inventory_hostname }} == 'Core'"
service:
name: aether.timer
state: disabled
running: no
- name: Set up the authorized_keys
template:
src: authorized_keys.j2
dest: /home/aether/.ssh/authorized_keys
mode: 0600
owner: aether
group: aether

18
roles/Chappaai/README.md Normal file
View File

@ -0,0 +1,18 @@
A Chappaai host is a gateway to accessing other hosts. It is a safeguard against admin error.
## Etymology
Chappaai hosts are named to follow the non-English naming of the Stargate network by the other denizens of the galaxy.
They are the first line of defense against administrative error -- similar to the way that [Stargate Command](https://stargate.fandom.com/wiki/Stargate_Command) was for Earth. They prevent admins from being locked out of correcting their changes and are connected to everything in the ecosystem. They also control DNS, which allows a sort of subliminal control of the entire ecosystem. This prevents infiltration by infections (similar to Goauld) and in fact can be the extinction of any DNS-enabled malware in the ecosystem by sinkholing the Command-and-Control.
## Capacity and Components
A Chappaai host needs minimal CPU or memory.
## Hosted Services and Entities
Chappaai should host a Pihole installation and [SSH](../Services/SSH.md). It should be linked by NAT to an obscure port to the outside world.
## Connections
Any host should be able to connect to a Chappaai with SSH and X11, and it should be able to dial to any service provider.
## Additional Reference
Chappaai hosts should be deployed alongside any Hypervisor. They can be as simple as a Pi-hole with SSH access, and they should be allowed to receive SSH connections from a non-tcp/22/ssh port.

View File

@ -17,7 +17,7 @@
- name: Ensure pihole web admin password
become: yes
command: "pihole -a -p {{ passwords['Nazara'] }}"
command: "pihole -a -p {{ passwords['Chappaai'] }}"
# when: pihole_install.changed
- name: Generate DNS/DHCP from inventory
@ -25,7 +25,7 @@
run_once: true
command: "python3 ../bin/generate-pihole-dns-dhcp.py {{ inventory_file }}"
- name: Nazara DNS
- name: Chappaai DNS
become: yes
register: dns_updated
copy:
@ -35,7 +35,7 @@
group: pihole
mode: 0644
- name: Nazara DHCP
- name: Chappaai DHCP
become: yes
register: dhcp_updated
copy:
@ -45,7 +45,7 @@
group: root
mode: 0644
- name: Nazara Configuration
- name: Chappaai Configuration
become: yes
register: conf_updated
copy:
@ -56,7 +56,7 @@
mode: 0644
- name: Nazara DHCP Leases dir
- name: Chappaai DHCP Leases dir
become: yes
file:
path: /var/lib/misc/
@ -65,7 +65,7 @@
group: root
mode: 0777
- name: Nazara DHCP Leases
- name: Chappaai DHCP Leases
become: yes
file:
path: /var/lib/misc/dnsmasq.leases

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

@ -52,7 +52,7 @@ a {
| sed "s/$ROW/$ANINIXROW/gI" \
| sed "s/$NAV/$ANINIXNAV/gI" \
| sed "s/$HOVER/$ANINIXHOVER/gI" \
| sed "s/$BGCOLOR/$ANINIXBG/gI" > /var/lib/gitea/custom/public/css/theme-aninix.css
| sed "s/$BGCOLOR/$ANINIXBG/gI" > /var/lib/gitea/custom/public/assets/css/theme-aninix.css
cd /var/lib/gitea/web-snippets
head="$(curl -ks https://aninix.net/ | grep -B 99999 -E '^<div class="home"')"
@ -60,5 +60,5 @@ foot="$(curl -ks https://aninix.net/ | grep -A 99999 -E '<footer>')"
for i in `find . -type f`; do
(echo "$head"
cat "$i"
echo "$foot") > /var/lib/gitea/custom/public/"$i".html
echo "$foot") > /var/lib/gitea/custom/public/assets/"$i".html
done

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

@ -17,7 +17,7 @@
<div class="ui stackable middle very relaxed page grid">
<div class="eight wide center column">
<h1 class="hero ui icon header">
<img width=20px height=20px src='/assets/img/icons/FoundationIcon.png'/>
<img width=20px height=20px src='/assets/img/icons/Foundation.png'/>
<a href="https://foundation.aninix.net/explore/repos">Open source security</a>
</h1>
<p class="large">
@ -26,7 +26,7 @@
</div>
<div class="eight wide center column">
<h1 class="hero ui icon header">
<img width=20px height=20px src='/assets/img/icons/IRCIcon.png'/>
<img width=20px height=20px src='/assets/img/icons/IRC.png'/>
<a href='ircs://aninix.net:6697/#lobby'>Contact us anytime</a>
</h1>
<p class="large">
@ -36,7 +36,7 @@
<div class="ui stackable middle very relaxed page grid">
<div class="eight wide center column">
<h1 class="hero ui icon header">
<img width=20px height=20px src="/assets/img/icons/WikiIcon.png"/>
<img width=20px height=20px src="/assets/img/icons/Wiki.png"/>
<a href="/AniNIX/Wiki">Open documentation</a>
</h1>
<p class="large">
@ -45,7 +45,7 @@
</div>
<div class="eight wide center column">
<h1 class="hero ui icon header">
<img width=20px height=20x src="/assets/img/icons/MaatIcon.png"/>
<img width=20px height=20x src="/assets/img/icons/Maat.png"/>
<a href="https://maat.aninix.net/">Downloads</a>
</h1>
<p class="large">
@ -60,10 +60,10 @@
<p>We host a number of web apps to make our users' lives easier.
</div>
<div class="ui stackable middle very relaxed page grid">
<div class="four wide center column"><a title="AniNIX/Singularity" href="https://singularity.aninix.net"><img style="width: 50px; height:auto; margin: 0; padding: 0 auto;" alt=RSS src="/assets/img/icons/SingularityIcon.png" /><p>AniNIX/Singularity (News powered by TT-RSS)</p></a></div>
<div class="four wide center column"><a title="AniNIX/Yggdrasil" href="https://yggdrasil.aninix.net"><img style="width: 50px; height:auto; margin: 0; padding: 0 auto;" src="/assets/img/icons/YggdrasilIcon.png" /><p>AniNIX/Yggdrasil (Media powered by Emby)</p></a></div>
<div class="four wide center column"><a title="AniNIX/Sharingan" href="https://sharingan.aninix.net"><img src="/assets/img/icons/SharinganIcon.png" style="width: 50px; height:auto; margin: 0; padding: 0 auto;" /><p>AniNIX/Sharingan (Monitoring powered by Nagios)</p></a></div>
<div class="four wide center column"><a title="AniNIX/WolfPack" href="https://wolfpack.aninix.net"><img src="/assets/img/icons/WolfPackIcon.png" style="width: 50px; height:auto; margin: 0; padding: 0 auto;" /><p>AniNIX/WolfPack (Botnet download results)</p></a></div>
<div class="four wide center column"><a title="AniNIX/Singularity" href="https://singularity.aninix.net"><img style="width: 50px; height:auto; margin: 0; padding: 0 auto;" alt=RSS src="/assets/img/icons/Singularity.png" /><p>AniNIX/Singularity (News powered by TT-RSS)</p></a></div>
<div class="four wide center column"><a title="AniNIX/Yggdrasil" href="https://yggdrasil.aninix.net"><img style="width: 50px; height:auto; margin: 0; padding: 0 auto;" src="/assets/img/icons/Yggdrasil.png" /><p>AniNIX/Yggdrasil (Media powered by Emby)</p></a></div>
<div class="four wide center column"><a title="AniNIX/Sharingan" href="https://sharingan.aninix.net"><img src="/assets/img/icons/Sharingan.png" style="width: 50px; height:auto; margin: 0; padding: 0 auto;" /><p>AniNIX/Sharingan (Monitoring powered by Graylog)</p></a></div>
<div class="four wide center column"><a title="AniNIX/Cyberbrain" href="https://cyberbrain.aninix.net"><img src="/assets/img/icons/Cyberbrain.png" style="width: 50px; height:auto; margin: 0; padding: 0 auto;" /><p>AniNIX/Cyberbrain (SFTP Dropbox)</p></a></div>
</div>
</div>
<hr style="margin-top: 50px;" />

View File

@ -2,7 +2,7 @@
<div class="sixteen wide center aligned centered column">
<!--<div class="ui negative message"><p>We are open despite COVID-19 -- those attending in person will need to sign a waiver of health and follow all state requirements, including wearing a mask.</p></div>-->
<div>
<img class="logo" src="/assets/img/icons/MartialArtsIcon.png" />
<img class="logo" src="/assets/img/icons/MartialArts.png" />
</div>
<div class="hero">
<h1 class="ui icon header title">
@ -16,7 +16,7 @@
<div class="ui stackable middle very relaxed page grid">
<div class="eight wide center column">
<h1 class="hero ui icon header">
<img width=20px height=20px src='/assets/img/icons/FoundationIcon.png'/>
<img width=20px height=20px src='/assets/img/icons/Foundation.png'/>
<a href="/mawiki">Open-source</a>
</h1>
<p class="large">
@ -35,13 +35,13 @@
<div class="ui stackable middle very relaxed page grid">
<div class="eight wide center column">
<h1 class="hero ui icon header">
<img width=20px height=20px src="/assets/img/icons/MartialArtsIcon.png"/>
<img width=20px height=20px src="/assets/img/icons/MartialArts.png"/>
<a href="/martialarts/index.html#storefront">Low-cost</a>
</h1>
<p class="large">We are non-profit group -- we train because we feel like it makes life better, not to make money. As such, our costs are publicly documented and our rates match the same. Classes will be informed of potential changes to costs well in advance, and we use recurring payments. We want you thinking about your training, not how you're going to pay for it.</p>
<p class="large">
<ul style="text-align: left;">
<li><b>Cost:</b> $10 per month in-person; $5 per month livestream -- pay below.</li>
<li><b>Cost:</b> Free</li>
<li><b>Lessons:</b>Tuesdays 7-8:30 p.m.</li>
<li><b>Sparring:</b>Tuesdays 6-7 p.m.</li>
<li><b>Shaolin Workouts:</b> Saturday mornings at 8 a.m. </li>
@ -51,7 +51,7 @@
</div>
<div class="eight wide center column">
<h1 class="hero ui icon header">
<img width=20px height=20x src="/assets/img/icons/IRCIcon.png"/>
<img width=20px height=20x src="/assets/img/icons/IRC.png"/>
<a href="/martialarts/index.html#social">Real-life First</a>
</h1>
<p class="large">

View File

@ -1,107 +1,82 @@
<div class="ui stackable middle very relaxed page grid">
<script src="https://js.stripe.com/v3"></script>
<div class="ui stackable middle very relaxed page grid">
<div class="sixteen wide center aligned centered column">
<!--<div class="ui negative message"><p>We are open despite COVID-19 -- those attending in person will need to sign a waiver of health and follow all state requirements, including wearing a mask.</p></div>-->
<div>
<img class="logo" src="/assets/img/icons/MartialArtsIcon.png" />
</div>
<div class="hero">
<h1 class="ui icon header title">
AniNIX
AniNIX Martial Arts
</h1>
<h2>Our Storefront</h2>
<p>We have limited service offerings available. Please contact an admin on IRC first to arrange the contract, then use the item below to pay the invoice.</p>
<h2>Open-source, research-driven self-defense and personal health</h2>
<p>AniNIX Martial Arts is a small martial arts collective focusing on research-driven martial arts. Our core style is USHF HapKiDo, but we are influenced by HEMA, Razmafzar, Kali, Shaolin, Silat, JKD, BJJ, and many other systems. We are a research-driven group -- we encourage cross-training with other systems and will bring in new concepts regularly. The class is open to all experience levels, gender identity, gender expression, sexual orientation, religious or cultural identity, socioecomic status, or age (above 14), in Southcentral Wisconsin -- we will fit your training to your needs and goals.</p><p>Drop-ins are welcome, and registration is cheap. We hope you'll give us a chance to show you what we can do.</p>
</div>
</div>
</div>
<div class="ui stackable middle very relaxed page grid">
<div class="sixteen wide center column" >
<div class="eight wide center column">
<h1 class="hero ui icon header">
<img width=20px height=20px src='/assets/img/icons/CoreIcon.png'/>
Cybersecurity Consulting
<img width=20px height=20px src='/assets/img/icons/FoundationIcon.png'/>
<a href="/mawiki">Open-source</a>
</h1>
<p class="large">The AniNIX offers cybersecurity consulting and advice services on a limited basis. We bill at $20 an hour -- please select your need below after negotiating with an admin.</p>
<p class="large">
<form action="./storefront.html" id="hours">
<label for="hourcount">Hours required</label>
<select name="hourcount" id="hourscount">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
</select>
<br/>
</form>
<!-- START STRIPE CODE -->
<!-- Create a button that your customers click to complete their purchase. Customize the styling to suit your branding. -->
<button
style="background-color:#6772E5;color:#FFF;padding:8px 12px;border:0;border-radius:4px;font-size:1em"
id="checkout-button-price_1HTuehI49P1uFPoXCW9pJg5E"
role="link"
type="button"
>
Checkout
</button>
<div id="error-message"></div>
<script>
(function() {
var stripe = Stripe('pk_live_51HThYnI49P1uFPoX5ARnHSpT9D08Gbfux6O25waFLpPBsnZoLDuqopFAZeLfu0CbbICxEnPZOOLkDLTlcNjkazs100ElKcF2QX');
var checkoutButton = document.getElementById('checkout-button-price_1HTuehI49P1uFPoXCW9pJg5E');
checkoutButton.addEventListener('click', function () {
// When the customer clicks on the button, redirect
// them to Checkout.
stripe.redirectToCheckout({
lineItems: [{price: 'price_1HTuehI49P1uFPoXCW9pJg5E', quantity: parseInt(document.getElementById('hourscount').value)}],
mode: 'payment',
// Do not rely on the redirect to the successUrl for fulfilling
// purchases, customers may not always reach the success_url after
// a successful payment.
// Instead use one of the strategies described in
// https://stripe.com/docs/payments/checkout/fulfill-orders
successUrl: window.location.protocol + '//aninix.net/pay/thank-you.html',
cancelUrl: window.location.protocol + '//aninix.net/pay/storefront.html',
})
.then(function (result) {
if (result.error) {
// If `redirectToCheckout` fails due to a browser or network
// error, display the localized error message to your customer.
var displayError = document.getElementById('error-message');
displayError.textContent = result.error.message;
}
});
});
})();
</script>
<! -- END STRIPE CODE -->
We want your training with our system to become a part of your life. This means that we provide access to a revision-controlled copy of our notes that all our students can download, keep, and contribute to. We're tired of the old era where how the system works is kept hidden from students and piecemealed out as a marketing ploy -- we want to be as trasparent as possible in how our program and our martial art function. Transparency keeps our instructors honest and our students engaged -- this means a better martial arts experience for everyone.
</p>
</div>
<div class="eight wide center column">
<h1 class="hero ui icon header">
<img width=20px height=20px src='/assets/img/ushf.jpg'/>
<a href='https://ushapkidofederation.wordpress.com/'>Research-driven</a>
</h1>
<p class="large">
Our system is always growing. We are a United States HapKiDo Federation (USHF) school, and that gives us access to high-quality instructors and seminar material each year from across the US. We also maintain good relationships with other schools in our area -- we want our students to examine what they're learing and make sure that it works, and that means looking at different perspectives.
</p> </div>
</div>
<div class="ui stackable middle very relaxed page grid">
<div class="eight wide center column">
<h1 class="hero ui icon header">
<img width=20px height=20px src="/assets/img/icons/MartialArtsIcon.png"/>
<a href="/martialarts/index.html#storefront">Low-cost</a>
</h1>
<p class="large">We are non-profit group -- we train because we feel like it makes life better, not to make money. As such, our costs are publicly documented and our rates match the same. Classes will be informed of potential changes to costs well in advance, and we use recurring payments. We want you thinking about your training, not how you're going to pay for it.</p>
<p class="large">
<ul style="text-align: left;">
<li><b>Cost:</b> $10 per month in-person; $5 per month livestream -- pay below.</li>
<li><b>Lessons:</b>Tuesdays 7-8:30 p.m.</li>
<li><b>Sparring:</b>Tuesdays 6-7 p.m.</li>
<li><b>Shaolin Workouts:</b> Saturday mornings at 8 a.m. </li>
<li><b>Location:</b> <a href="https://g.page/aninix-martial-arts?share">225 Blaser Drive, Belleville, WI</a></li>
<li><b>What to bring:</b> Exercise clothes and water</li>
</ul></p>
</div>
<div class="eight wide center column">
<h1 class="hero ui icon header">
<img width=20px height=20x src="/assets/img/icons/IRCIcon.png"/>
<a href="/martialarts/index.html#social">Real-life First</a>
</h1>
<p class="large">
Everyone is welcome! Class attendance is not mandated and belt-testing is not required to train. As a courtesy, please inform the class of your absence or intended late arrival -- real-life comes first, and we're happy to work with your needs. As long as one person shows, we'll have class -- the smaller the class, the more tailored it is, but the bigger classes mean more partners and body types.</p>
<p class="large">
Our focus is also on what you will actually use. While we appreciate traditional and esoteric training for self-development, our weekly classes are focused on modern techniques and training methods so that you get the most out of your time. Our goal is to help create a community of prepared and healthy citizens, and we believe martial arts helps build that in a way no other activity can.
</p>
</div>
</div>
<div class="ui stackable middle very relaxed page grid">
<div class="sixteen wide center column" >
<hr style="margin-top: 50px;" />
<h2>Donate</h2>
<p>If you like what we do, you can also donate on one of these platforms:</p>
<ul style="width:500px;text-align: left;margin:auto;">
<li><a href="https://store.steampowered.com/wishlist/id/darkfeather664/#sort=order">Steam (games)</a></li>
<li><a href="https://www.amazon.com/hz/wishlist/ls/3CORZU03RNWST?ref_=wl_share">Amazon (hardware)</a></li>
<li>BTC 38Nd3SgytdvSmcX3gfHeNAE2B6aPyYbS7s</li>
<li>Coinbase USDC 0x21a05e628Ed622F7594f62Ea3C764bAEF7fE3Bf3</li>
</ul>
</div>
<div class="ui stackable middle very relaxed page grid" id="social">
<div class="sixteen wide center aligned centered column">
<div class="hero">
<h2 id=social>Follow us on social media</h2>
<p class=large>We want to stay in touch with you, so we are present on the social media platforms we find applicable.<br/> Have one you want us on? Contact us and let us know!</p>
</div>
<div class="ui stackable middle very relaxed page grid" id="social">
<div class="two wide center column"><p>&nbsp;</p></div>
<div class="two wide center column"><a title=RSS href="/martialarts/maqotw.xml"><img style="width: 50px; height:auto; margin: 0; padding: 0 auto;" alt=RSS src="/assets/img/social/rss.png" /></a></div>
<div class="two wide center column"><a title=Discord href="https://discord.gg/2bmggfR"><img alt=Discord style="width: 50px; height:auto; margin: 0; padding: 0 auto;" src="/assets/img/social/discord.ico" /></a></div>
<div class="two wide center column"><a title=NextDoor href="https://nextdoor.com/news_feed/?post=112835813"><img alt=NextDoor src="/assets/img/social/nextdoor.png" style="width: 50px; height:auto; margin: 0; padding: 0 auto;" /></a></div>
<div class="two wide center column"><a title=YouTube href="https://www.youtube.com/channel/UCVAkee-WaInnZbPn16bqzrw/about?view_as=subscriber"><img src="/assets/img/social/youtube.png" style="width: 50px; height:auto; margin: 0; padding: 0 auto;" /></a></div>
<div class="two wide center column"><a title=Strava href="https://www.strava.com/clubs/aninixmartialarts"><img style="width: 50px; height:auto; margin: 0; padding: 0 auto;" src="/assets/img/social/strava.png" /></a></div>
<div class="two wide center column"><a title=Facebook href="https://www.facebook.com/groups/aninixmartialarts/"><img style="width: 50px; height:auto; margin: 0; padding: 0 auto;" src="/assets/img/social/facebook.png" /></a></div>
<div class="two wide center column"><p>&nbsp;</p></div>
</div>
</div>
</div>

View File

@ -1,12 +0,0 @@
<div class="ui stackable middle very relaxed page grid">
<div class="sixteen wide center aligned centered column">
<div>
<img class="logo" src="/assets/img/icons/CoreIcon.png" />
</div>
<div class="hero">
<h2 class="ui icon header title">
Thank you for your purchase!
</h2>
</div>
</div>
</div>

View File

@ -5,12 +5,6 @@
name:
- gitea
- name: BitBot
become: yes
git:
repo: https://github.com/jesopo/bitbot.git
dest: /opt/bitbot
- name: Make directories
become: yes
file:
@ -27,7 +21,7 @@
register: config
template:
src: app.ini.j2
dest: /var/lib/gitea/custom/conf/app.ini
dest: /etc/gitea/app.ini
owner: gitea
group: gitea
mode: 0750
@ -53,7 +47,7 @@
become: yes
get_url:
url: https://github.com/BenZuser/Emby-Web-Dark-Themes-CSS/raw/master/RED/theme.css
dest: /var/lib/gitea/custom/public/css/emby-web-dark-theme-BenZuser.css
dest: /var/lib/gitea/custom/public/assets/css/emby-web-dark-theme-BenZuser.css
owner: gitea
group: gitea
@ -65,23 +59,20 @@
owner: gitea
group: gitea
- name: Service file
become: yes
register: servicefile
copy:
src: foundation.service
dest: /usr/lib/systemd/system
owner: root
group: root
mode: 0755
- name: Ensure default service disabled
- name: Ensure internal service disabled
become: yes
ignore_errors: yes
service:
name: gitea
name: foundation
state: stopped
enabled: no
- name: Ensure internal service is absent
become: yes
file:
path: /usr/lib/systemd/system/foundation.service
state: absent
- name: Generate pages
become: yes
register: custompages
@ -89,8 +80,8 @@
- name: Restart service
become: yes
when: config.changed or servicefile.changed or custompages.changed
when: config.changed or custompages.changed
service:
name: foundation
name: gitea
state: restarted
enabled: yes

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)
@ -457,8 +457,8 @@ GC_INTERVAL_TIME = 86400
SESSION_LIFE_TIME = 86400
[picture]
AVATAR_UPLOAD_PATH = data/avatars
REPOSITORY_AVATAR_UPLOAD_PATH = data/repo-avatars
AVATAR_UPLOAD_PATH = avatars
REPOSITORY_AVATAR_UPLOAD_PATH = repo-avatars
; How Gitea deals with missing repository avatars
; none = no avatar will be displayed; random = random avatar will be displayed; image = default image will be used
REPOSITORY_AVATAR_FALLBACK = none
@ -501,7 +501,7 @@ FORMAT =
[log]
ROOT_PATH = %(GITEA_WORK_DIR)/log
MODE = console
LEVEL = Info
LEVEL = Warn
STACKTRACE_LEVEL = None
logger.router.MODE = ,
logger.xorm.MODE = ,
@ -516,9 +516,9 @@ BUFFER_LEN = 10000
ACCESS_LOG_TEMPLATE = {{ '{{' }}.Ctx.RemoteAddr{{ '}}' }} - {{ '{{' }}.Identity{{ '}}' }} {{ '{{' }}.Start.Format "[02/Jan/2006:15:04:05 -0700]" {{ '}}' }} "{{ '{{' }}.Ctx.Req.Method{{ '}}' }} {{ '{{' }}.Ctx.Req.RequestURI{{ '}}' }} {{ '{{' }}.Ctx.Req.Proto{{ '}}' }}" {{ '{{' }}.ResponseWriter.Status{{ '}}' }} {{ '{{' }}.ResponseWriter.Size{{ '}}' }} "{{ '{{' }}.Ctx.Req.Referer{{ '}}' }}\" \"{{ '{{' }}.Ctx.Req.UserAgent{{ '}}' }}"
logger.access.MODE = console
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
LEVEL = Info
LEVEL = Warn
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "None"
STACKTRACE_LEVEL = Critical
STACKTRACE_LEVEL = None
; Generic log modes
[log.x]

View File

@ -9,35 +9,23 @@ https://aur.archlinux.org/brscan4.git
https://aur.archlinux.org/carbonyl-bin.git
https://aur.archlinux.org/castnow-git.git
https://aur.archlinux.org/ccrypt.git
https://aur.archlinux.org/chromium-pepper-flash.git
https://aur.archlinux.org/defcon.git
https://aur.archlinux.org/discord-cli-git.git
https://aur.archlinux.org/discord-irc.git
https://aur.archlinux.org/downgrader.git
https://aur.archlinux.org/dotnet-core-bin.git
https://aur.archlinux.org/dotnet-runtime-bin.git
https://aur.archlinux.org/freeme2.git
https://aur.archlinux.org/genymotion.git
https://aur.archlinux.org/gnome-alsamixer.git
https://aur.archlinux.org/google-chrome.git
https://aur.archlinux.org/google-earth.git
https://aur.archlinux.org/googlecl.git
https://aur.archlinux.org/googler.git
https://aur.archlinux.org/graylog.git
https://aur.archlinux.org/graylog-collector-sidecar.git
https://aur.archlinux.org/gsa.git
https://aur.archlinux.org/gstreamer0.10-ffmpeg.git
https://aur.archlinux.org/gtk-xfce-engine.git
https://aur.archlinux.org/gvmd.git
https://aur.archlinux.org/gyazo.git
https://aur.archlinux.org/helloworld.git
https://aur.archlinux.org/injection.git
https://aur.archlinux.org/inspircd.git
https://aur.archlinux.org/irker.git
https://aur.archlinux.org/jmtpfs.git
https://aur.archlinux.org/jpcsp.git
https://aur.archlinux.org/js.git
https://aur.archlinux.org/kpcli.git
https://aur.archlinux.org/lib32-glib.git
https://aur.archlinux.org/libdaq.git
https://aur.archlinux.org/libdwarf-20140413.git
@ -50,28 +38,22 @@ https://aur.archlinux.org/mkinitcpio-utils.git
https://aur.archlinux.org/mpir.git
https://aur.archlinux.org/mongodb-bin.git
https://aur.archlinux.org/mongodb-tools-bin.git
https://aur.archlinux.org/mongosh-bin.git
https://aur.archlinux.org/nordvpn-bin.git
https://aur.archlinux.org/oinkmaster.git
https://aur.archlinux.org/openresty.git
https://aur.archlinux.org/openvas-scanner.git
https://aur.archlinux.org/openvisualtraceroute.git
https://aur.archlinux.org/ospd.git
https://aur.archlinux.org/ospd-openvas.git
https://aur.archlinux.org/ossec-local.git
https://aur.archlinux.org/pwm.git
https://aur.archlinux.org/pcmciautils.git
https://aur.archlinux.org/pdfshuffler.git
https://aur.archlinux.org/pear-net-ldap2.git
https://aur.archlinux.org/perl-clipboard.git
https://aur.archlinux.org/perl-crypt-rijndael.git
https://aur.archlinux.org/perl-expect.git
https://aur.archlinux.org/perl-file-keepass.git
https://aur.archlinux.org/perl-net-sftp-foreign.git
https://aur.archlinux.org/perl-php-serialization.git
https://aur.archlinux.org/perl-sys-mmap.git
https://aur.archlinux.org/perl-term-shellui.git
https://aur.archlinux.org/php-pear.git
https://aur.archlinux.org/php-zts.git
https://aur.archlinux.org/pm-utils.git
https://aur.archlinux.org/powerpanel.git
https://aur.archlinux.org/python-aiohttp.git
@ -92,16 +74,14 @@ https://aur.archlinux.org/savage.git
https://aur.archlinux.org/self-service-password.git
https://aur.archlinux.org/smarty3.git
https://aur.archlinux.org/suricata.git
https://aur.archlinux.org/swfdec.git
https://aur.archlinux.org/swfdec-gnome.git
https://aur.archlinux.org/systemdjournal2gelf.git
https://aur.archlinux.org/tor-browser-en.git
https://aur.archlinux.org/tor-browser-bin.git
https://aur.archlinux.org/trid.git
https://aur.archlinux.org/tt-rss-auth-ldap-git.git
https://aur.archlinux.org/udisks.git
https://aur.archlinux.org/undvd.git
https://aur.archlinux.org/uniglot.git
https://aur.archlinux.org/unvanquished.git
https://aur.archlinux.org/unvanquished-data.git
https://aur.archlinux.org/vbam-gtk.git
https://aur.archlinux.org/xfce4-mixer.git
https://aur.archlinux.org/xorg-server-utils.git

View File

@ -1,14 +0,0 @@
port: 9129
download_timeout: 3600 # download will timeout after 3600 seconds
cache_dir: /var/cache/pacoloco
purge_files_after: 360000 # 360000 seconds or 100 hours, 0 to disable
repos:
archlinux:
urls:
- http://mirrors.gigenet.com/archlinux/
- http://mnvoip.mm.fcix.net/archlinux/
- http://mirrors.kernel.org/archlinux/
- http://ftp.osuosl.org/pub/archlinux/
- https://mnvoip.mm.fcix.net/archlinux/
- http://southfront.mm.fcix.net/archlinux/
user_agent: Pacoloco

View File

@ -17,6 +17,7 @@
- name: Maat configuration
become: yes
register: aurlist
copy:
src: aur.list
dest: /usr/local/etc/Maat/aur.list
@ -28,6 +29,13 @@
state: restarted
enabled: yes
- name: Start Maat build cycle
become: yes
when: aurlist.changed
service:
name: maat.service
state: started
- name: Generate mirrorlist
delegate_to: localhost
run_once: yes

View File

@ -1,16 +0,0 @@
A Nazara host is a gateway to accessing other hosts. It is a safeguard against admin error.
## Etymology
Nazara hosts are named because they are the first line of defense against administrative error -- they prevent admins from being locked out of correcting their changes and are connected to everything in the ecosystem. They also control DNS, which allows a sort of subliminal control of the entire ecosystem. This is akin to the mastermind [Reaper AI](https://masseffect.fandom.com/wiki/Sovereign) from the Mass Effect franchise, and in fact can be the extinction of any DNS-enabled malware in the ecosystem by sinkholing the Command-and-Control.
## Capacity and Components
A Nazara host needs minimal CPU or memory.
## Hosted Services and Entities
Nazara should host a Pihole installation and [SSH](../Services/SSH.md). It should be NAT'ed to an obscure port to the outside world.
## Connections
Any host should be able to connect to a Nazara with SSH and X11, and it should be able to dial to any service provider.
## Additional Reference
Nazara hosts should be deployed alongside any Hypervisor. They can be as simple as a Pi-hole with SSH access, and they should be allowed to receive SSH connections from a non-tcp/22/ssh port.

View File

@ -61,3 +61,11 @@
when: qemubr.changed or br0.changed
debug:
msg: You may need to restart VMs on the Node.
- name: Enable VMs
become: yes
with_items: "{{ active_vms }}"
service:
name: "{{ item }}-vm.service"
state: started
enabled: yes

View File

@ -1,14 +0,0 @@
[Unit]
Description=AniNIX/{{ inventory_hostname }}
After=network.target
[Service]
ExecStart=/usr/sbin/qemu-system-x86_64 -name AniNIX/{{ inventory_hostname }} -machine type=pc,accel=kvm -bios /usr/share/edk2-ovmf/x64/OVMF.fd -cpu host -smp {{ cores }} {{ disks }} -net nic,macaddr={{ mac }},model=virtio -net bridge,br={{ bridge }} -vga std -nographic -vnc :{{ vnc }} -m size={{ memory }}G -device virtio-rng-pci
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=always
User=root
Group=root
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,3 @@
#!/bin/bash
slapcat -a "(!(entryDN:dnSubtreeMatch:=ou=People,dc=aninix,dc=net))"

View File

@ -0,0 +1,119 @@
dn: dc=aninix,dc=net
objectClass: dcObject
objectClass: organization
dc: aninix
o: AniNIXUsers
description: AniNIX::LDAP Crediential Directory
structuralObjectClass: organization
entryUUID: a521b05a-3532-4042-bf8f-3631a1e51b94
creatorsName: cn=root,dc=aninix,dc=net
createTimestamp: 20160901205333Z
entryCSN: 20160901205333.449191Z#000000#000#000000
modifiersName: cn=root,dc=aninix,dc=net
modifyTimestamp: 20160901205333Z
dn: cn=root,dc=aninix,dc=net
objectClass: organizationalRole
cn: root
description: Directory Manager
structuralObjectClass: organizationalRole
entryUUID: 9e4273d9-d002-4015-a774-bed02afd6cc9
creatorsName: cn=root,dc=aninix,dc=net
createTimestamp: 20160901205333Z
pwdLastSuccess: 20220918222625Z
entryCSN: 20220918222625.132392Z#000000#000#000000
modifiersName: cn=root,dc=aninix,dc=net
modifyTimestamp: 20220918222625Z
dn: ou=Group,dc=aninix,dc=net
ou: Group
objectClass: top
objectClass: organizationalUnit
structuralObjectClass: organizationalUnit
entryUUID: 475e1ae1-d992-4a9a-85de-e7f71974ac03
creatorsName: cn=root,dc=aninix,dc=net
createTimestamp: 20160901214257Z
entryCSN: 20160901214257.941445Z#000000#000#000000
modifiersName: cn=root,dc=aninix,dc=net
modifyTimestamp: 20160901214257Z
dn: cn=ldapuser,ou=Group,dc=aninix,dc=net
cn: ldapuser
gidNumber: 10000
objectClass: posixGroup
objectClass: top
structuralObjectClass: posixGroup
entryUUID: dc17d42d-fae9-496d-b362-82f27679476c
creatorsName: cn=root,dc=aninix,dc=net
createTimestamp: 20160903051753Z
entryCSN: 20160903051753.156600Z#000000#000#000000
modifiersName: cn=root,dc=aninix,dc=net
modifyTimestamp: 20160903051753Z
dn: cn=hypervisorauth,ou=Group,dc=aninix,dc=net
cn: hypervisorauth
gidNumber: 10001
objectClass: posixGroup
objectClass: top
structuralObjectClass: posixGroup
entryUUID: 88cb5e2c-ee93-4d62-a83a-63ceff9ceba0
creatorsName: cn=root,dc=aninix,dc=net
createTimestamp: 20160903061147Z
memberUid: lurso3
entryCSN: 20160903061653.689826Z#000000#000#000000
modifiersName: cn=root,dc=aninix,dc=net
modifyTimestamp: 20160903061653Z
dn: ou=pwpolicies,dc=aninix,dc=net
ou: pwpolicies
objectClass: top
objectClass: organizationalUnit
structuralObjectClass: organizationalUnit
entryUUID: ee2c6fc6-a40a-4d6f-992e-c1a04439f022
creatorsName: cn=root,dc=aninix,dc=net
createTimestamp: 20161029155416Z
entryCSN: 20161029155416.247439Z#000000#000#000000
modifiersName: cn=root,dc=aninix,dc=net
modifyTimestamp: 20161029155416Z
dn: cn=default,ou=pwpolicies,dc=aninix,dc=net
objectClass: pwdPolicy
objectClass: person
objectClass: top
cn: default
sn: Default
pwdAttribute: userPassword
pwdMaxAge: 31536000
pwdExpireWarning: 604800
pwdInHistory: 12
pwdCheckQuality: 1
pwdMaxFailure: 5
pwdLockout: TRUE
pwdLockoutDuration: 86400
pwdGraceAuthNLimit: 3
pwdFailureCountInterval: 3600
pwdMustChange: TRUE
pwdMinLength: 8
pwdAllowUserChange: TRUE
pwdSafeModify: FALSE
structuralObjectClass: person
entryUUID: f983ea45-deca-4b8f-8e55-cebbacf392ba
creatorsName: cn=root,dc=aninix,dc=net
createTimestamp: 20161029171109Z
entryCSN: 20161029171109.930559Z#000000#000#000000
modifiersName: cn=root,dc=aninix,dc=net
modifyTimestamp: 20161029171109Z
dn: cn=DarkFeather,ou=Group,dc=aninix,dc=net
cn: DarkFeather
gidNumber: 10002
objectClass: posixGroup
objectClass: top
memberUid: DarkFeather
structuralObjectClass: posixGroup
entryUUID: 1f333fb2-0611-4235-ba07-aa9fa0edb439
creatorsName: cn=root,dc=aninix,dc=net
createTimestamp: 20201018201805Z
entryCSN: 20201018201805.104347Z#000000#000#000000
modifiersName: cn=root,dc=aninix,dc=net
modifyTimestamp: 20201018201805Z

View File

@ -0,0 +1,26 @@
binlist = ldap-adduser ldap-userreport ldap-resetpass
filelist = sample-user.ldif
compile:
@echo Nothing to do
install: clean ${binlist} ${filelist}
mkdir -p ${pkgdir}/opt/aninix/Password/
for i in ${filelist}; do install -m 0640 -o ldap -g ldap $$i ${pkgdir}/opt/aninix/Password/; done
mkdir -p ${pkgdir}/usr/local/sbin/
for i in ${binlist}; do install -m 0750 -o root -g root $$i ${pkgdir}/usr/local/sbin; done
test: compile
@echo Nothing to do
clean:
@echo Nothing to do.
diff:
@echo Nothing to do.
reverse:
@echo Nothing to do.
checkperm:
@echo Nothing to do.

View File

@ -0,0 +1,46 @@
depends=('bash>=4.4' 'openldap')
makedepends=('make>=4.2')
checkdepends=()
optdepends=()
pkgname="Password-Scripts"
pkgver="$(git describe --tag --abbrev=0)"."$(git rev-parse --short HEAD)"
pkgrel=1
pkgrel() {
echo $(( `git log "$(git describe --tag --abbrev=0)"..HEAD | grep -c commit` + 1 ))
}
epoch="$(git log | grep -c commit)"
pkgdesc="AniNIX/Password Scripts"
arch=("x86_64")
url="$(git config remote.origin.url | sed 's/.git$//')"
license=('custom')
groups=()
provides=("${pkgname}")
conflicts=()
replaces=("${pkgname,,}" "aninix-${pkgname,,}")
backup=()
options=()
install=
changelog=
source=()
noextract=()
md5sums=()
validpgpkeys=()
prepare() {
git pull || true
}
build() {
make -C ..
}
check() {
chmod -R u+r ../pkg
make -C .. test
}
package() {
export pkgdir="${pkgdir}"
make -C .. install
install -D -m644 ../../../../LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
}

View File

@ -43,16 +43,17 @@ if [ "$?" -eq 0 ]; then
read answer
if [ "$answer" == "YES" ]; then
file="/etc/openldap/users.d/$username.ldif"
cp /usr/local/src/ConfigPackages/Sora/sample-user.ldif "$file"
cp /opt/aninix/Password/sample-user.ldif "$file"
line="$(grep -E '^uid: ' "$file")"; sed -i "s/$line/uid: $username/" "$file"
line="$(grep -E '^dn: ' "$file" | cut -f 2 -d ' ' | cut -f 1 -d ',')"; sed -i "s/$line/uid=$username/" "$file"
line="$(grep -E '^homeDirectory: ' "$file")"; sed -i "s#$line#homeDirectory: /home/$username/#" "$file"
line="$(grep -E '^homeDirectory: ' "$file")"; sed -i "s#$line#homeDirectory: /$username/#" "$file"
line="$(grep -E '^cn: ' "$file")"; sed -i "s/$line/cn: $username/" "$file"
line="$(grep -E '^mail: ' "$file")"; sed -i "s#$line#mail: ircs://aninix.net:6697/$username#" "$file"
line="$(grep -E '^uidNumber: ' "$file")"; sed -i "s/$line/uidNumber: $newuserid/" "$file"
ldapadd -D 'cn=root,dc=aninix,dc=net' -y /root/.ldappass -f "$file"
ldapadd -D 'cn=root,dc=aninix,dc=net' -W -f "$file"
ldap-resetpass "$username"
# usermod -a -G ssh-allow,passwdchange "$username"
# Create default home
cp -r /etc/skel "/home/$username"; chmod 0027 "/home/$username"; chown -R "$username": "/home/$username"
fi
rmdir "$lockfile"
exit 0;

View File

@ -7,11 +7,11 @@ if [ -z "$uid" ]; then
exit 1
fi
ldappasswd -D 'cn=root,dc=aninix,dc=net' -y /root/.ldappass "uid=$uid,ou=People,dc=aninix,dc=net"
ldappasswd -D 'cn=root,dc=aninix,dc=net' -W "uid=$uid,ou=People,dc=aninix,dc=net"
if [ `ldapsearch -x "(uid=$uid)" + \* | grep -c shadowLastChange\:` -ne 0 ]; then
(printf "dn: uid=$uid,ou=People,dc=aninix,dc=net\nchangetype: modify\ndelete: shadowLastChange\n\n") | ldapmodify -D 'cn=root,dc=aninix,dc=net' -y /root/.ldappass &>/dev/null;
(printf "dn: uid=$uid,ou=People,dc=aninix,dc=net\nchangetype: modify\ndelete: shadowLastChange\n\n") | ldapmodify -D 'cn=root,dc=aninix,dc=net' -W &>/dev/null;
fi
(printf "dn: uid=$uid,ou=People,dc=aninix,dc=net\nchangetype: modify\nadd: shadowLastChange\nshadowLastChange: 0\n\ndn: uid=$uid,ou=People,dc=aninix,dc=net\nchangetype: modify\nadd: pwdReset\npwdReset: TRUE\n\n") | ldapmodify -D 'cn=root,dc=aninix,dc=net' -y /root/.ldappass &>/dev/null;
(printf "dn: uid=$uid,ou=People,dc=aninix,dc=net\nchangetype: modify\nadd: shadowLastChange\nshadowLastChange: 0\n\ndn: uid=$uid,ou=People,dc=aninix,dc=net\nchangetype: modify\nadd: pwdReset\npwdReset: TRUE\n\n") | ldapmodify -D 'cn=root,dc=aninix,dc=net' -W &>/dev/null;
exit $?

View File

@ -8,17 +8,9 @@ function shortshow() {
echo ${user}": "$email
}
function queryLDAPAttribute() {
ldapsearch -x "$1" "$2" | grep -E "${2}: " | sed "s/^${2}: //"
}
basedn=`ldapsearch -x '(cn=root)' dn | grep -E ^dn:\ | sed 's/dn: cn=root,//'`
maxAge="$(queryLDAPAttribute '(cn=default)' pwdMaxAge)"
changeAge=$(( $maxAge - 2592000 ))
deleteAge=$(( 2 * $maxAge ))
for user in `queryLDAPAttribute '(uid=*)' uid`; do
for user in `ldapsearch -x -b "ou=People,$basedn" '(uid=*)' uid | grep -E ^uid:\ | sed 's/^uid: //'`; do
# Pull changed stats
lastChanged=`/usr/sbin/ldapsearch -x "(uid=$user)" + | grep pwdChangedTime | cut -f 2 -d ' '`
@ -45,7 +37,7 @@ for user in `queryLDAPAttribute '(uid=*)' uid`; do
if [ "$lastChanged" == "$errortext" ]; then
shortshow
else
if [ $delta -gt "$changeAge" ] && [ $delta -lt "$maxAge" ]; then shortshow; fi
if [ $delta -gt 28512000 ] && [ $delta -lt 31536000 ]; then shortshow; fi
fi
;;
"--expired")
@ -53,11 +45,6 @@ for user in `queryLDAPAttribute '(uid=*)' uid`; do
shortshow;
fi
;;
"--removeable")
if [ "$lastChanged" != "$errortext" ] && [ "$delta" -ge "$deleteAge" ]; then
shortshow;
fi
;;
*)
cat
;;

View File

@ -0,0 +1,21 @@
dn: uid=testuser,ou=People,dc=aninix,dc=net
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: testuser
cn: Test User
sn: User
givenName: Test
title: User
telephoneNumber: +0 000 000 0000
mobile: +0 000 000 0000
postalAddress: AddressLine1$AddressLine2$AddressLine3
loginShell: /bin/bash
uidNumber: 10006
gidNumber: 10000
homeDirectory: /home/testuser
description: Work contact
mail: testuser@aninix.net

View File

@ -0,0 +1,35 @@
---
- name: Create the base config
become: yes
template:
src: slapd.ldif
dest: /etc/openldap/slapd.ldif
owner: ldap
group: ldap
mode: 0640
- name: Create the directories
file:
path: "{{ item }}"
owner: ldap
group: ldap
mode: 0700
loop:
- /var/lib/openldap/openldap-data/
- /etc/openldap
- /etc/openldap/users.d
- /etc/openldap/groups.d
- /etc/openldap/slapd.d
- name: Initialize the instance
become: yes
command:
cmd: slapadd -n 0 -F /etc/openldap/slapd.d/ -l /etc/openldap/config.ldif && chown -R ldap: /etc/openldap
creates: /etc/openldap/slapd.d/cn=config
- name: Ensure the service
become: yes
service:
name: slapd
state: restarted
enabled: yes

View File

@ -0,0 +1,17 @@
---
- name: Set login config
become: yes
template:
src: nslcd.conf.j2
dest: /etc/nslcd.conf
owner: nslcd
group: nslcd
mode: 0600
- name: Ensure login service
become: yes
service:
name: nslcd
state: restarted
enabled: yes

View File

@ -0,0 +1,13 @@
---
- name: Sora packages
become: yes
package:
name:
- openldap
- Password-Scripts
- include_tasks: daemon.yml
- include_tasks: login.yml
- include_tasks: web.yml

View File

@ -0,0 +1,24 @@
---
- name: Clone the web portal
become: yes
git:
repo: https://github.com/ltb-project/self-service-password
dest: /usr/share/webapps/self-service-password
- name: Ensure web portal ownership
file:
state: directory
owner: http
group: http
path: /usr/share/webapps/self-service-password
recurse: true
- name: Web portal config
become: yes
template:
src: config.inc.php.j2
dest: /usr/share/webapps/self-service-password/conf/config.inc.php
owner: http
group: http
mode: 0600

View File

@ -41,21 +41,23 @@ ChallengeResponseAuthentication no
HostbasedAuthentication no
KerberosAuthentication no
GSSAPIAuthentication no
DenyGroups [^ssh-allow]
AllowGroups ssh-allow
PermitRootLogin no
PermitEmptyPasswords no
## Access Controls
Match Group ssh-forward
## By default, only ssh-allow or ldapusers are allowed to sftp
AllowGroups ssh sftp ldapuser
Match Group ldapuser,sftp
ForceCommand internal-sftp
ChrootDirectory /home
## Special groups are allowed shell
Match Group wheel,ssh-allow
AllowTcpForwarding yes
PermitTunnel yes
AllowAgentForwarding yes
X11Forwarding yes
Match Group sftp-home-jail
ForceCommand internal-sftp
ChrootDirectory /home
ForceCommand none
ChrootDirectory none
# Allow other packages to ship snippets
Include /etc/ssh/includes/*

View File

@ -34,15 +34,14 @@
name: "{{ item }}"
state: present
loop:
- ssh-allow
- ssh-forward
- sftp-home-jail
- ssh
- sftp
- name: Add SSH user to ssh-allow
- name: Add SSH user to ssh group
become: yes
user:
name: "{{ ansible_user_id }}"
groups: ssh-allow
groups: ssh
append: yes
- name: Copy the SSH key
@ -75,7 +74,7 @@
file:
path: /etc/ssh/includes
state: directory
user: root
owner: root
group: root
mode: 0755

View File

@ -37,30 +37,20 @@
group: http
mode: 2755
- name: Copy TLSA script
- name: Remove old TLSA script
become: yes
file:
path: /usr/local/sbin/tlsa-generation.bash
state: absent
- name: Copy record generator script
become: yes
template:
src: tlsa-generation.bash.j2
dest: /usr/local/sbin/tlsa-generation.bash
src: record-generation.bash.j2
dest: /usr/local/sbin/record-generation.bash
owner: root
group: root
mode: 0700
- name: Get proposed TLSA records
become: yes
command: /usr/local/sbin/tlsa-generation.bash
register: tlsa_records
- name: Show proposed TLSA records
debug:
msg: "{{ tlsa_records.stdout_lines }}"
- name: Get TLSA records
delegate_to: localhost
run_once: yes
command: "/bin/bash -c 'printf _443._tcp\\ ; dig _443._tcp.{{ external_domain }} TLSA +short; printf _6697._tcp\\ ; dig _6697._tcp.{{ external_domain }} TLSA +short'"
register: ext_tlsa_records
- name: Show TLSA records
debug:
msg: "{{ ext_tlsa_records.stdout_lines }}"
- debug:
msg: 'Run `sudo /usr/local/sbin/record-generation.bash` to generate a zonefile for import into a DNS provider.'

View File

@ -0,0 +1,44 @@
#!/bin/bash
ttl=86400
externalip="$(curl -s ident.me)"
for domain in {{ hosted_domains }} {{ external_domain }}; do
echo
# NS/MX/A -- basic orientation to the world for names, mail, and address
cat <<EOM
\$ORIGIN ${domain}.
@ $ttl IN SOA ns51.cloudns.net. support.cloudns.net. 2024040128 7200 1800 1209600 86400
@ $ttl IN NS ns51.cloudns.net.
@ $ttl IN NS ns52.cloudns.net.
@ $ttl IN NS ns53.cloudns.net.
@ $ttl IN NS ns54.cloudns.net.
@ $ttl IN MX 10 mailforward51.cloudns.net.
@ $ttl IN MX 10 mailforward52.cloudns.net.
@ $ttl IN A ${externalip}
EOM
# CAA -- who can issue certs for this domain
# https://letsencrypt.org/docs/caa/
echo 'CAA 128 issue "letsencrypt.org"'
# TLSA -- TLS fingerprints for certs & chain
for i in _443._tcp _6697._tcp; do
printf "$i $ttl IN ";
openssl x509 -in /etc/letsencrypt/live/{{ sslidentity }}/chain.pem -noout -pubkey 2>/dev/null | openssl rsa -pubin -outform DER 2>/dev/null | openssl dgst -sha256 -hex 2>/dev/null | awk '{print "TLSA 2 1 1", $NF}'
printf "$i $ttl IN ";
openssl x509 -in /etc/letsencrypt/live/{{ sslidentity }}/cert.pem -noout -pubkey 2>/dev/null | openssl rsa -pubin -outform DER 2>/dev/null | openssl dgst -sha256 -hex 2>/dev/null | awk '{print "TLSA 3 1 1", $NF}'
done
# SSHFP -- SFTP/SSH fingerprints
ssh-keygen -r '@ $ttl' | grep -E '4 2|1 2' # Only take RSA & Ed25519 keys
done
# CNAME -- Add CNAMES for various subdomains
for i in {{ external_subdomains }}; do
printf "%-20s %-10s %-10s %-10s %s\n" "$i" "$ttl" IN CNAME {{ external_domain }}.
done

View File

@ -1,4 +0,0 @@
#!/bin/bash
openssl x509 -in /etc/letsencrypt/live/{{ sslidentity }}/chain.pem -noout -pubkey | openssl rsa -pubin -outform DER | openssl dgst -sha256 -hex | awk '{print "le-ca TLSA 2 1 1", $NF}'
openssl x509 -in /etc/letsencrypt/live/{{ sslidentity}}/cert.pem -noout -pubkey | openssl rsa -pubin -outform DER | openssl dgst -sha256 -hex | awk '{print "cert TLSA 3 1 1", $NF}'

View File

@ -0,0 +1,6 @@
################################################################################
# AniNIX/Node0 #
# #
# This is the network virtualization platform. VMs can be found with this: #
# cd /usr/lib/systemd/system; ls -1 *vm.service | xargs -n 1 systemctl status #
################################################################################

View File

@ -0,0 +1,6 @@
################################################################################
# AniNIX/Node0 #
# #
# This is the network virtualization platform. VMs can be found with this: #
# cd /usr/lib/systemd/system; ls -1 *vm.service | xargs -n 1 systemctl status #
################################################################################

View File

@ -0,0 +1,6 @@
################################################################################
# AniNIX/Node0 #
# #
# This is the network virtualization platform. VMs can be found with this: #
# cd /usr/lib/systemd/system; ls -1 *vm.service | xargs -n 1 systemctl status #
################################################################################

View File

@ -0,0 +1,6 @@
################################################################################
# AniNIX/Node0 #
# #
# This is the network virtualization platform. VMs can be found with this: #
# cd /usr/lib/systemd/system; ls -1 *vm.service | xargs -n 1 systemctl status #
################################################################################

View File

@ -0,0 +1,6 @@
################################################################################
# AniNIX/Node0 #
# #
# This is the network virtualization platform. VMs can be found with this: #
# cd /usr/lib/systemd/system; ls -1 *vm.service | xargs -n 1 systemctl status #
################################################################################

View File

@ -0,0 +1,5 @@
################################################################################
# AniNIX/Nazara #
# #
# This is the network DNS/DHCP service, using Raspberry Pi pihole, and bastion #
################################################################################

View File

@ -1,3 +1 @@
# AniNIX/Geth Hardware Platform (Raspbian Rpi 1 B+) #

View File

@ -1,3 +1 @@
# AniNIX/Geth Hardware Platform (Raspbian Rpi 1 B+) #

View File

@ -1,3 +1 @@
# AniNIX/Geth Hardware Platform (Raspberry Pi 3 Model B Plus Rev 1.3) #

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
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
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
copy:
src: netctl-tun
dest: "/etc/netctl/tun0"

View File

@ -0,0 +1,57 @@
---
- name: Test root password
ignore_errors: yes
register: root_password_test
vars:
ansible_become_user: "{{ item }}"
ansible_become_method: su
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
command: id
loop:
- root
- "{{ ansible_user_id }}"
- name: Define passwords
ignore_errors: yes
vars:
ansible_become_user: "root"
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
when: root_password_test.rc is not defined or root_password_test.rc != 0
command:
cmd: /bin/bash -l -c "echo '{{item}}:{{ passwords[inventory_hostname] }}' | chpasswd {{ item }}"
loop:
- root
- "{{ ansible_user_id }}"
- name: Ensure deploy user has sudo permissions.
vars:
ansible_become_method: su
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
copy:
dest: /etc/sudoers.d/basics
content: "{{ ansible_user_id }} ALL=(ALL) NOPASSWD: ALL\n"
- name: Ensure we include /etc/sudoers.d (Current)
vars:
ansible_become_method: su
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
when: ansible_architecture != "armv6l"
lineinfile:
path: /etc/sudoers
regexp: "includedir /etc/sudoers.d"
line: "@includedir /etc/sudoers.d"
- name: Ensure we include /etc/sudoers.d (Legacy)
vars:
ansible_become_method: su
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
when: ansible_architecture == "armv6l"
lineinfile:
path: /etc/sudoers
regexp: "includedir /etc/sudoers.d"
line: "#includedir /etc/sudoers.d"

View File

@ -4,160 +4,7 @@
# This is an AniNIX convention to allow password management by Ansible.
- name: Test root password
ignore_errors: yes
register: root_password_test
vars:
ansible_become_user: "{{ item }}"
ansible_become_method: su
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
command: id
loop:
- root
- "{{ ansible_user_id }}"
- name: Define passwords
ignore_errors: yes
vars:
ansible_become_user: "root"
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
when: root_password_test.rc is not defined or root_password_test.rc != 0
command:
cmd: /bin/bash -l -c "echo '{{item}}:{{ passwords[inventory_hostname] }}' | chpasswd {{ item }}"
loop:
- 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
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
copy:
dest: /etc/sudoers.d/basics
content: "{{ ansible_user_id }} ALL=(ALL) NOPASSWD: ALL\n"
- name: Ensure we include /etc/sudoers.d (Current)
vars:
ansible_become_method: su
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
when: ansible_architecture != "armv6l"
lineinfile:
path: /etc/sudoers
regexp: "includedir /etc/sudoers.d"
line: "@includedir /etc/sudoers.d"
- name: Ensure we include /etc/sudoers.d (Legacy)
vars:
ansible_become_method: su
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
when: ansible_architecture == "armv6l"
lineinfile:
path: /etc/sudoers
regexp: "includedir /etc/sudoers.d"
line: "#includedir /etc/sudoers.d"
- name: Set up pacman.conf
vars:
ansible_become_password: "{{ passwords[inventory_hostname] }}"
ignorepkg: "{{ holdpackages | default('') }}"
become: yes
template:
src: pacman.conf.j2
dest: /etc/pacman.conf
owner: root
group: root
mode: 0644
when: ansible_os_family == "Archlinux"
- name: Set mirror
become: yes
when: ansible_os_family == "Archlinux"
copy:
content: |
Server = {{ mirroruri }}
dest: /etc/pacman.d/mirrorlist.shadowarch
owner: root
group: root
mode: 0644
- name: Set up apt sources.list
vars:
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
copy:
content: |
deb http://archive.raspberrypi.org/debian/ bullseye main
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://archive.raspberrypi.org/debian/ bullseye main
dest: /etc/apt/sources.list.d/raspi.list
owner: root
group: root
mode: 0644
when: ansible_os_family == "Debian"
- name: Install ShadowArch (ArchLinux)
vars:
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
pacman:
name: ShadowArch
state: present
update_cache: yes
when: ansible_os_family == "Archlinux"
- name: Set up AniNIX-specific repository location (Other)
when: ansible_os_family != "Archlinux"
vars:
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
file:
path: /opt/aninix
state: directory
- name: Download ShadowArch (Other)
vars:
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
ignore_errors: yes
git:
repo: 'https://foundation.aninix.net/AniNIX/ShadowArch'
dest: '/opt/aninix/ShadowArch'
update: yes
when: ansible_os_family != "Archlinux"
- name: Install ShadowArch (Other)
vars:
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
command:
chdir: '/opt/aninix/ShadowArch'
cmd: '/bin/bash -c "make install"'
when: ansible_os_family != "Archlinux"
- include_tasks: authentication.yml
- name: Set up hostname
vars:
@ -166,14 +13,18 @@
hostname:
name: "{{ inventory_hostname }}.{{ replica_domain }}"
- include: archlinux-network.yml
- include_tasks: archlinux-network.yml
when: ansible_os_family == "Archlinux"
- include: raspbian-network.yml
- include_tasks: raspbian-network.yml
when: ansible_os_family == "Debian"
- include: dns.yml
- include_tasks: dns.yml
- include: ntp.yml
- include_tasks: ntp.yml
- include: bash.yml
- include_tasks: repositories.yml
- include_tasks: bash.yml
- include_tasks: shadowarch.yml

View File

@ -0,0 +1,67 @@
---
- name: Set up pacman.conf
vars:
ansible_become_password: "{{ passwords[inventory_hostname] }}"
ignorepkg: "{{ holdpackages | default('') }}"
become: yes
template:
src: pacman.conf.j2
dest: /etc/pacman.conf
owner: root
group: root
mode: 0644
when: ansible_os_family == "Archlinux"
- name: Set mirror
become: yes
when: ansible_os_family == "Archlinux"
copy:
content: |
Server = {{ mirroruri }}
dest: /etc/pacman.d/mirrorlist.shadowarch
owner: root
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] }}"
become: yes
copy:
content: |
deb http://archive.raspberrypi.org/debian/ bullseye main
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://archive.raspberrypi.org/debian/ bullseye main
dest: /etc/apt/sources.list.d/raspi.list
owner: root
group: root
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
state: present
update_cache: yes

View File

@ -0,0 +1,39 @@
---
- name: Install ShadowArch (ArchLinux)
vars:
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
pacman:
name: ShadowArch
state: present
update_cache: yes
when: ansible_os_family == "Archlinux"
- name: Set up AniNIX-specific repository location (Other)
when: ansible_os_family != "Archlinux"
vars:
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
file:
path: /opt/aninix
state: directory
- name: Download ShadowArch (Other)
vars:
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
ignore_errors: yes
git:
repo: 'https://foundation.aninix.net/AniNIX/ShadowArch'
dest: '/opt/aninix/ShadowArch'
update: yes
when: ansible_os_family != "Archlinux"
- name: Install ShadowArch (Other)
vars:
ansible_become_password: "{{ passwords[inventory_hostname] }}"
become: yes
command:
chdir: '/opt/aninix/ShadowArch'
cmd: '/bin/bash -c "make install"'
when: ansible_os_family != "Archlinux"

View File

@ -2,4 +2,7 @@ Description="Bridge connection"
Interface=br0
Connection=bridge
BindsToInterfaces=({{ ipinterface }} tun0)
IP=dhcp
IP=static
Address=('{{ ip }}/24')
Gateway='{{ router }}'
DNS=('{{ dns }}')

View File

@ -102,8 +102,8 @@ Include = /etc/pacman.d/mirrorlist.shadowarch
[AniNIX]
SigLevel = Required DatabaseOptional
Server = https://maat.aninix.net/
Server = http://maat.msn0.aninix.net/
[aur]
SigLevel = Required DatabaseOptional
Server = https://maat.aninix.net/aur/
Server = http://maat.msn0.aninix.net/aur/

View File

@ -10,7 +10,7 @@ auto lo
iface lo inet loopback
iface {{ ipinterface }} inet static
address {{ ansible_host }}/{{ netmask }}
address {{ ip }}/{{ netmask }}
gateway {{ router }}
auto wlan0

View File

@ -0,0 +1,3 @@
check program check_archlinux_wkd with path "/usr/bin/systemctl is-failed archlinux-keyring-wkd-sync.service"
if status == 0 for 1 times within 5 cycles then exec "/usr/bin/systemctl reset-failed archlinux-keyring-wkd-sync.service"
if status == 0 for 5 times within 5 cycles then exec "/etc/monit.d/scripts/critical CRITICAL: Archlinux Keyring WKD Sync has failed and automated remediation has not solved it."

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/automated_response"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,3 +1,4 @@
include "/etc/monit.d/checks/system"
include "/etc/monit.d/checks/vips"
include "/etc/monit.d/checks/availability"
include "/etc/monit.d/checks/automated_response"

View File

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

View File

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

View File

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

View File

@ -2,3 +2,4 @@ include "/etc/monit.d/checks/system"
include "/etc/monit.d/checks/watcher-of-watchers"
include "/etc/monit.d/checks/warrant-canary"
include "/etc/monit.d/checks/grimoire"
include "/etc/monit.d/checks/automated_response"

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

Some files were not shown because too many files have changed in this diff Show More