diff --git a/.gitignore b/.gitignore index e61bca2..09f7d51 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +roles/Vanik/files +venv/ + # ---> Python # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..cbc07b6 --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +pkgdirname != basename `git config remote.origin.url` | sed 's/.git$$//' + +compile: + @echo Nothing to do + +install: clean + mkdir -p ${pkgdir}/opt/aninix/${pkgdirname}/ + rsync -avzp HelloWorld* ${pkgdir}/opt/aninix/${pkgdirname}/ + +test: compile + python3 -m pytest + +clean: + cat .gitignore | xargs rm -Rf + +diff: + @echo Nothing to do. + +reverse: + @echo Nothing to do. + +checkperm: + @echo Nothing to do. + diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 0000000..68bc55e --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,46 @@ +depends=('bash>=4.4', 'ansible>=2.9') +makedepends=('make>=4.2') +checkdepends=() +optdepends=() +pkgname="$(git config remote.origin.url | rev | cut -f 1 -d '/' | rev | sed 's/.git$//')" +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="$(head -n 1 README.md)" +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 +} + +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" +} diff --git a/README.md b/README.md index c6be0de..c2f6adf 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,29 @@ -# Tenebrous +This project will discover and provide inventory intelligence to Sora, Shadowfeed, Geth, and Sharingan. It is named after the fictional Star Wars Imperial Intelligence organization that oversaw the various divisions of Intelligence and orchestrated their operations. + +*Note*: This project is in progress -- former Makefiles from [ConfigPackages](/AniNIX/ConfigPackages) are being upgraded into Ansible playbooks here. + +# How to use + +This project expects that you use an Ansible vault for credentials. Create one and add this to your `.bashrc`. +``` +export ANSIBLE_VAULT_PASSWORD_FILE=$HOME/password-store/${organization}.vault.password +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. + +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/). + +Then, use the SSHkey playbook to copy your key and the deploy playbook to set things up. +``` +ansible-playbook -i your-inventory.yml playbooks/sshkey.yml +ansible-playbook -i your-inventory.yml playbooks/deploy.yml +``` + +Happy hacking! + + + + + -This project will discover and provide inventory intelligence to Sora, Shadowfeed, Geth, and Sharingan. It is named after the fictional Tenebrous from the SWTOR game. \ No newline at end of file diff --git a/examples/msn0.yml b/examples/msn0.yml new file mode 100644 index 0000000..4c90d96 --- /dev/null +++ b/examples/msn0.yml @@ -0,0 +1,35 @@ +all: + vars: + replica_domain: MSN0.AniNIX.net + dns: 10.0.1.7 + children: + prod: + hosts: + Core: + interface: enp1s0f0 + ip: 10.0.1.3 + mac: 00:25:90:0d:6e:86 + type: wired + dev: + hosts: + DarkNet: + MaatBuilder: + Maat: + Sharingan: + geth: + hosts: + GethHub1: + GethHub2: + GethHub3: + Nazara: + tachikoma: + hosts: + Tachikoma: + Dedsec: + tricorder: + hosts: + DarkFeather: + Lykos: + windows: + hosts: + Games: diff --git a/modules/netdetect.py b/modules/netdetect.py new file mode 100644 index 0000000..80ce23d --- /dev/null +++ b/modules/netdetect.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 + +# File: modules/net-detect +# +# Description: This module detects network hosts and creates an Ansible playbook for them. +# +# Package: AniNIX/Tenebrous +# Copyright: WTFPL +# +# Author: DarkFeather + +import os +import re +import nmap3 +import yaml + +prdre = re.compile('core*') +devre = re.compile('darknet*|maat*|sharingan*|') +gethre = re.compile('geth*|nazara*') +shadowfeedre = re.compile('shadowfeed*') +nmap = nmap3.Nmap() + +function main(): + """ + Main operation + """ + + + diff --git a/playbooks/deploy.yml b/playbooks/deploy.yml new file mode 100644 index 0000000..0265589 --- /dev/null +++ b/playbooks/deploy.yml @@ -0,0 +1,100 @@ +--- +# deploy.yml +# +# This playbook details how an entire datacenter should be deployed +# +# Parameters: +# threads: Number of threads to use; default is 8. + +- hosts: all + order: sorted + serial: "{{ threads | default('8') }}" + gather_facts: true + ignore_unreachable: true + vars_files: + - "{{ lookup('env', 'ANSIBLE_VAULT_FILE') }}" + vars: + + roles: + - basics + - networking + - SSH + - Sharingan-Data + +- hosts: DarkNet + order: sorted + serial: "{{ threads | default('8') }}" + gather_facts: true + ignore_unreachable: true + vars_files: + - "{{ lookup('env', 'ANSIBLE_VAULT_FILE') }}" + vars: + + roles: + - DarkNet + - SSH + +- hosts: Core + order: sorted + serial: "{{ threads | default('8') }}" + gather_facts: true + ignore_unreachable: true + vars_files: + - "{{ lookup('env', 'ANSIBLE_VAULT_FILE') }}" + vars: + + roles: + - SSL + - Yggdrasil + - WebServer + - Foundation + - IRC + - Sharingan-IDS + +- hosts: Maat + order: sorted + serial: "{{ threads | default('8') }}" + gather_facts: true + ignore_unreachable: true + vars_files: + - "{{ lookup('env', 'ANSIBLE_VAULT_FILE') }}" + vars: + + roles: + - Maat + +- hosts: Sharingan + order: sorted + serial: "{{ threads | default('8') }}" + gather_facts: true + ignore_unreachable: true + vars_files: + - "{{ lookup('env', 'ANSIBLE_VAULT_FILE') }}" + vars: + + roles: + - Sharingan + +- hosts: MaatBuilder + order: sorted + serial: "{{ threads | default('8') }}" + gather_facts: true + ignore_unreachable: true + vars_files: + - "{{ lookup('env', 'ANSIBLE_VAULT_FILE') }}" + vars: + + roles: + - MaatBuilder + +- hosts: Nazara + order: sorted + serial: "{{ threads | default('8') }}" + gather_facts: true + ignore_unreachable: true + vars_files: + - "{{ lookup('env', 'ANSIBLE_VAULT_FILE') }}" + vars: + + roles: + - MaatBuilder diff --git a/playbooks/geth-major-patch.yml b/playbooks/geth-major-patch.yml new file mode 100644 index 0000000..40db891 --- /dev/null +++ b/playbooks/geth-major-patch.yml @@ -0,0 +1,62 @@ +--- +# patching.yml +# +# This playbook can be used to patch all the servers in an inventory to the latest on the repo servers +# Variables: +# - hosts: the host grouper in the inventory -- default: all +# - action: update or upgrade -- default: update +# - delay: minutes to wait after a reboot -- default 5 +# +# +# Patch then restart a node +- hosts: "{{ targetlist | default('all') }}" + order: sorted + ignore_unreachable: true + serial: 1 + vars: + ansible_become: yes + ansible_become_user: root + ansible_become_method: sudo + oldmajor: stretch + newmajor: buster + tasks: + - name: Check /var free percentage + command: /bin/bash -c "df -m /var | tail -n 1 | awk '{ print $5; }' | sed 's/%//' " + become: no + register: df_output + + - name: Verify /var space + assert: + that: + - 90 > {{ df_output.stdout }} + fail_msg: "Not enough free space" + + - apt: + name: python-apt + state: present + + - name: apt dist-upgrade + apt: + update_cache: yes + upgrade: dist + ignore_errors: yes + + - name: Replace repo + command: "sed -i 's/{{ oldmajor }}/{{ newmajor }}/g' /etc/apt/sources.list" + become: yes + + - name: Update packages + apt: + upgrade: full + update_cache: yes + autoremove: yes + autoclean: yes + ignore_errors: yes + + # - name: Perform firmware-update + # command: rpi-update + # become: yes + + - reboot: + + - wait_for_connection: diff --git a/playbooks/one-role.yml b/playbooks/one-role.yml new file mode 100644 index 0000000..36eda60 --- /dev/null +++ b/playbooks/one-role.yml @@ -0,0 +1,28 @@ +# --- +# one-role.yml +# +# Test a single role against a host or group of hosts. +# +# Parameters: +# targets: group in the inventory to use +# threads: number of simultaneous executions +# role: role to run +# sshport (optional): override 22/tcp/ssh for Ansible control +# +# Expects ANSIBLE_VAULT_FILE to be set in the environment to path the vault +# Also set ANSIBLE_VAULT_PASSWORD_FILE to your password file location if you want it. +# +- hosts: "{{ targets | default('all') }}" + order: sorted + serial: "{{ threads | default('8') }}" + gather_facts: true + ignore_unreachable: true + vars: + ansible_ssh_port: "{{ sshport | default('22') }}" + therole: "{{ role | default('Uptime') }}" + vars_files: + - "{{ lookup('env', 'ANSIBLE_VAULT_FILE') }}" + + roles: + - "{{ therole }}" + diff --git a/playbooks/patching-verification.yml b/playbooks/patching-verification.yml new file mode 100644 index 0000000..59fc815 --- /dev/null +++ b/playbooks/patching-verification.yml @@ -0,0 +1,27 @@ +--- +# patching.yml +# +# Variables: +# - hosts: what hosts in the inventory to use +# - threads: how many to check in parallel +- hosts: "{{ hosts | default('all') }}" + order: sorted + serial: "{{ threads | default('4') }}" + ignore_unreachable: true + vars: + ansible_become: no + tasks: + + - name: Check updates + yum: + list=updates + update_cache=true + ignore_errors: true + register: yumupdates + + - name: Patching succeeded + ignore_errors: true + assert: + that: + - yumupdates.results|length == 0 + - df_output.stdout is search("rhel-7-server-rpms-nist") diff --git a/playbooks/patching.yml b/playbooks/patching.yml new file mode 100644 index 0000000..c881eb9 --- /dev/null +++ b/playbooks/patching.yml @@ -0,0 +1,52 @@ +--- +# patching.yml +# +# This playbook can be used to patch all the servers in an inventory to the latest on the repo servers +# Variables: +# - hosts: the host grouper in the inventory -- default: all +# - action: update or upgrade -- default: update +# - delay: minutes to wait after a reboot -- default 5 +# +# +# Patch then restart a node +- hosts: "{{ hosts | default('all') }}" + order: sorted + ignore_unreachable: true + serial: 1 + vars: + ansible_become: yes + ansible_become_user: root + ansible_become_method: sudo + vars_files: + - "{{ playbook_dir }}/../.vault" + tasks: + - name: Check /var free percentage + command: /bin/bash -c "df -m /var | tail -n 1 | awk '{ print $5; }' | sed 's/%//' " + become: no + register: df_output + + - name: Verify /var space + assert: + that: + - 90 > {{ df_output.stdout }} + fail_msg: "Not enough free space" + + - name: Patching + ignore_errors: yes + yum: + name: '*' + state: latest + update_cache: yes + # disablerepo: '*' + enablerepo: rhel-7-server-rpms-nist + + register: patching_output + + - debug: + msg: "{{ patching_output }}" + + - name: Reboot + reboot: + + - name: Wait for reboot + wait_for_connection: diff --git a/playbooks/roles b/playbooks/roles new file mode 120000 index 0000000..7b9ade8 --- /dev/null +++ b/playbooks/roles @@ -0,0 +1 @@ +../roles/ \ No newline at end of file diff --git a/playbooks/sshkey.yml b/playbooks/sshkey.yml new file mode 100644 index 0000000..ca55cf3 --- /dev/null +++ b/playbooks/sshkey.yml @@ -0,0 +1,45 @@ +# --- +# sshkey.yml +# +# ssh-keyscan and copy your SSH key to hosts +# +# Parameters: +# targets: group in the inventory to use +# threads: number of simultaneous executions +# pubkey: file to hand off +# sshport (optional): override 22/tcp/ssh for Ansible control +# +# Expects ANSIBLE_VAULT_FILE to be set in the environment to path the vault +# +- hosts: "{{ targets | default('all') }}" + order: sorted + serial: "{{ threads | default('8') }}" + gather_facts: false + ignore_unreachable: true + vars: + ansible_ssh_port: "{{ sshport | default('22') }}" + keyfile: "{{ pubkey | default(lookup('env','HOME') + '/.ssh/id_rsa.pub') }}" + vars_files: + - "{{ lookup('env', 'ANSIBLE_VAULT_FILE') }}" + + tasks: + - name: Get key + delegate_to: localhost + command: "cat {{ keyfile }}" + register: key + + # Thanks to https://gist.github.com/shirou/6928012 + - name: Ensure ssh host key known + delegate_to: localhost + lineinfile: + dest: ~/.ssh/known_hosts + create: yes + state: present + line: "{{ lookup('pipe', 'ssh-keyscan -trsa -p' + ansible_ssh_port + ' ' + inventory_hostname) }}" + + - authorized_key: + user: "{{ lookup('env','USER') }}" + key: "{{ key.stdout }}" + state: present + exclusive: true + name: "Pass authorized key" diff --git a/playbooks/vars-debugging.yml b/playbooks/vars-debugging.yml new file mode 100644 index 0000000..f0d163c --- /dev/null +++ b/playbooks/vars-debugging.yml @@ -0,0 +1,29 @@ +# --- +# one-role.yml +# +# Test a single role against a host or group of hosts. +# +# Parameters: +# targets: group in the inventory to use +# threads: number of simultaneous executions +# variablename: the variable to print +# sshport (optional): override 22/tcp/ssh for Ansible control +# +# Expects ANSIBLE_VAULT_FILE to be set in the environment to path the vault +# Also set ANSIBLE_VAULT_PASSWORD_FILE to your password file location if you want it. +# +- hosts: "{{ targets | default('all') }}" + order: sorted + serial: "{{ threads | default('8') }}" + gather_facts: true + ignore_unreachable: true + vars: + ansible_ssh_port: "{{ sshport | default('22') }}" + variablename: "{{ variable | default('ansible_os_family') }}" + vars_files: + - "{{ lookup('env', 'ANSIBLE_VAULT_FILE') }}" + + tasks: + - debug: + msg: "{{ lookup('vars', variablename) }}" + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..af40201 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +pyaml +pytest +python3-nmap +simplejson diff --git a/roles/DarkNet/tasks/main.yml b/roles/DarkNet/tasks/main.yml new file mode 100644 index 0000000..e7e29da --- /dev/null +++ b/roles/DarkNet/tasks/main.yml @@ -0,0 +1,9 @@ +--- + + - name: DarkNet packages + become: yes + package: + name: + - WolfPack + - deluge + - nordvpn-bin diff --git a/roles/Foundation/README.md b/roles/Foundation/README.md new file mode 100644 index 0000000..930d11a --- /dev/null +++ b/roles/Foundation/README.md @@ -0,0 +1,65 @@ +The Foundation is a one-stop shop for source code from AniNIX developers -- it's an open repository form which people can pull source code and recreate the entities being used by the AniNIX. You can view its web frontend from [https://aninix.net/foundation this webpage]. + +# Etymology +The etymology of the Foundation is twofold. First and foremost, the AniNIX attempts to automate any new package it is using as much as possible, and as such the Foundation holds the very basis on which the AniNIX is built. + +Secondly, the Foundation is the third piece of the charity trinity for the AniNIX, along with the Wiki and the [https://aninix.net/pages/charity.php short-term charity projects]. The AniNIX puts a lot of time into designing its projects and making sure they work. Rather than forcing others to redo this work, we offer commented code and documentation so that the process is transparent but the work-by-hand is minimized.[[Category:Charity]] + +# Relevant Files and Software +The Git system was created by the Linux project to manage changes to the kernel and has been on the rise for some time among Version Control Systems (VCS's) with projects like GitHub. The AniNIX self-hosts the repositories in [file:///srv/foundation/ the Foundation server folder] on [[Core]]. + +[[WebServer]] is configured to translate the repository to [https://aninix.net/foundation/ the Web-accessible format] via the ArchLinux cgit package. Review the package list at that link and identify the source packages you want to use. Then use the following to clone the source, generally best done to /usr/local/src/ on Linux. Please note that the AniNIX uses Webserver translation to eliminate the need for a .git suffix -- web requests will show in CGIT, while Git clone requests will pull the package all from the same URL. Right-click on your package of choice from the web interface's index page and then clone that address.
+git clone https://aninix.net/foundation/
+
+ +New packages should make sure to refer to the [[Development Best Practices]] to ensure they are compliant with standards; if you notice an issue with the Foundation's code, make sure to submit a [[QANs|QAN]]. [[TeamGreen|AniNIX::TeamGreen]] should be running regressions on these projects. + +You can use [https://aur.archlinux.org/packages/hexedit-advanced-search/ Hexedit] to edit [file:///usr/share/webapps/cgit/cgit.cgi cgit.cgi] to have a different name, such as "AniNIX::Foundation Web". + +## Dependencies +For CentOS, one needs to use the following steps to install Mono. Packages like Cryptoworkbench, Heartbeat, Cerberus, and others require this. +* yum install bison gettext glib2 freetype fontconfig libpng libpng-devel libX11 libX11-devel glib2-devel libgdi* libexif glibc-devel urw-fonts java unzip gcc gcc-c++ automake autoconf libtool make bzip2 wget +* [https://download.mono-project.com/sources/mono/ Download Mono source] +* tar xjvf the source package +* configure; make; make install + +*Note:* We used to declare the INSTALLER variable at the top of Makefiles, but no longer do. Non-ShadowArch installs should double check dependencies against the PKGBUILD files manually. We will try to keep this list short. + +# Available Clients +To get a client to access the Foundation, use one of the following or visit +* ArchLinux: pacman -S git +* Ubuntu: apt-get install git +* RHEL/CentOS: yum install git +* Windows: [https://git-scm.com/download/win Go here], but please be aware that file paths and such are coded for Linux. Windows users will need to conduct extensive code review to install these packages. +* Mac: [https://git-scm.com/download/mac Go here] + +Each package will need to be checked out individually. + +**Alternatively**: ArchLinux users can add the following segment to the bottom of pacman.conf to install the packages as bundled by the AniNIX. We're working on adding GPG signing -- in the meantime, security-conscious users should build from source anyway. +
+[AniNIX::Foundation]
+SigLevel = Optional TrustAll
+Server = https://aninix.net/foundation/
+
+ +# Equivalents or Competition +The most famous equivalent is [https://github.com GitHub]. Other source code control systems exist, including some provided by employers or academic institutions -- GitLab provides an enterprise-style implementation. Other protocol implementations vary widely -- Mercurial, Bazaar, and SVN are other revision control systems others use. We appreciate the flexibility of Git. + +# Additional Reference +Some core Git tools are leveraged in specific ways for the AniNIX. + +## Config for Author +Even though the [[Talk:IRC#Why_Not_SMTP|AniNIX doesn't use SMTP]], we still use the @aninix.net suffix for the user.email config property on branches. All commits, therefore, should have the proper-case of the user's [[IRC|AniNIX::IRC]] handle as the user.name attribute, and the lower-cased username followed by @aninix.net for the user.email attribute. + +## Tags for Semantic Versioning +We version our projects according to [https://semver.org/ Semantic Versioning] -- this versioning is established using the git tag as major and minor version, the git commit as the patch, and the number of commits since the tag as the ArchLinux release note. + +[https://aninix.net/cgit/cgit.cgi/HelloWorld/tree/PKGBUILD Our HelloWorld PKGBUILD] demonstrates this -- most of the metadata for the package is populated directly by git, and only dependencies are tracked in the PKGBUILD itself. + +## Branches for Functional Improvements +All major functional improvements being worked should be tracked in a branch. The branch name should be the same as the [[QANs|QAN]] for which the branch was started or the functional concept's shortname. + +## Filter-branch to Prune +Git maintains a history of all files. If you need to remove files permanently, GitHub maintains [https://help.github.com/articles/removing-sensitive-data-from-a-repository/ an article] on how to use "git filter-branch" to purge it. +}} +[[Category:Public_Service]] \ No newline at end of file diff --git a/roles/Foundation/tasks/main.yml b/roles/Foundation/tasks/main.yml new file mode 100644 index 0000000..1164c79 --- /dev/null +++ b/roles/Foundation/tasks/main.yml @@ -0,0 +1,14 @@ +--- + - name: Base packages + become: yes + package: + name: + - gitea + + - name: BitBot + git: + repo: https://github.com/jesopo/bitbot.git + dest: /opt/bitbot + + + diff --git a/roles/Geth/README.md b/roles/Geth/README.md new file mode 100644 index 0000000..aad12be --- /dev/null +++ b/roles/Geth/README.md @@ -0,0 +1,20 @@ +Geth is a complete automation suite for homes and interaction with the physical world. However, it is not a automatic process, and as such you will need to install it manually. + +# Etymology=The [http://masseffect.wikia.com/wiki/Geth Geth] are a fictional race in the Mass Effect universe. Geth are individual processes running on many platforms. The more devices, the smarter the collective or gestalt consciousness of the entity becomes. + +# Relevant Files and Software +You can install Geth with [https://aninix.net/foundation/ConfigPackages ConfigPackages]'s Geth Makefile and configuration. + +A number of devices can be controlled under the gestalt -- see [[Geth/Hardware]] for our experiments with Geth hardware platforms. The configuration.yaml format used by the underlying home-assistant package is very simple, and as such we don't prescriptively install one over the base version. Instead, we include snippets for you to define your own structure. + +We are also considering features such as integrating smart lights with Shadowfeed presence detection and timeslots and requiring wireless presence for RFC door unlocks. + +[file:///var/lib/hass/ Geth configuration] can be tested with the following:
 hass --script check_config -c /var/lib/hass
+ +# Available Clients +See [[WebServer#Clients|this list of clients]] for tools to access this system. The Shadowfeed NAT rules will need to be updated to allow access outside the network, and make sure to follow [https://home-assistant.io/getting-started/securing/ the security checkpoints] before publishing. + +# Equivalents or Competition +Most home-automation systems are DIY at the moment, though the [https://nest.com/ NEST] system is one commercial offering. +}} +[[Category:SSL]] \ No newline at end of file diff --git a/roles/Geth/tasks/main.yml b/roles/Geth/tasks/main.yml new file mode 100644 index 0000000..5210a0a --- /dev/null +++ b/roles/Geth/tasks/main.yml @@ -0,0 +1,7 @@ +--- + - name: Geth packages + become: yes + package: + name: + - openhab2 + diff --git a/roles/Grimoire/README.md b/roles/Grimoire/README.md new file mode 100644 index 0000000..e3ed443 --- /dev/null +++ b/roles/Grimoire/README.md @@ -0,0 +1,22 @@ +Grimoire is a PostgreSQL database underlying other systems on the AniNIX, including [AniNIX/Singularity](../Singularity) + +# Etymology +A [grimoire](http://en.wikipedia.org/wiki/Grimoire) is historically a collection of magical knowledge and the ability summon spirits or daemons. Similarly, Singularity adds knowledge to be read from the Grimoire, and Wiki includes the methodology to start the daemon processes being run on the network. + +# Relevant Files and Software +Grimoire has a user, postgres, with a home directory of `/var/lib/postgres/`. This user's bashrc contains some help text on how to reset passwords and backup databases in PostgreSQL. + +## Backups +Backups are provided by [AniNIX/Aether](../Aether). They can be restored with the following: +
+psql -U dbuser -d db -f backup.sql
+
+ +# Available Clients +There are no clients for the Grimoire -- Singularity and Wiki maintain their tables. + +# Additional Reference +Make sure to read the [PostgreSQL page on ArchWiki](https://wiki.archlinux.org/index.php/PostgreSQL) to understand how to maintain this system. + +# Tables +* Singularity controls the ttrss database. diff --git a/roles/Grimoire/tasks/main.yml b/roles/Grimoire/tasks/main.yml new file mode 100644 index 0000000..880e139 --- /dev/null +++ b/roles/Grimoire/tasks/main.yml @@ -0,0 +1,8 @@ +--- + + - name: Grimoire packages + become: yes + package: + name: + - postgresql + diff --git a/roles/IRC/README.md b/roles/IRC/README.md new file mode 100644 index 0000000..bae4bf2 --- /dev/null +++ b/roles/IRC/README.md @@ -0,0 +1,53 @@ +IRC is a chat system used by members of the AniNIX network. See [[IRC#Available Clients|Available Clients]] for access methods. + +# Etymology +[https://en.wikipedia.org/wiki/IRC IRC] stands for Internet Relay Chat -- it is a method of text-based communication across the network via various servers. IRC has long been the self-hosted communication medium of choice for hackers, developers, and the fringe -- though overall adoption has dropped a bit with the rise of other social media, networks like [https://freenode.org Freenode] are growing. IRChttps://royal.pingdom.com/2012/04/24/irc-is-dead-long-live-irc/ is moving to the hacker niche, and we follow along. + +# Relevant Files and Software +The configuration for the IRC service is divided into two parts -- the daemon and services. +## InspIRCd +The IRC daemon is powered by [https://inspircd.org/ InspIRCd 2][[Category:InspIRCd]]. Relevant configuration is in [file:///etc/inspircd/inspircd.conf the conf file] and it logs to [file:///var/log/inspircd/startup.log startup.log]. +## Anope +The services component is supplied by [https://www.anope.org/ Anope 2][[Category:Anope]]. Relevant configuration is in [file:///etc/anope/services.conf the services.conf] and it logs to the [file:///var/log/anope/ the anope log]. + +Anope also takes backups of [file:///var/db/anope/anope.db the anope database] to the backups folder in the same location. [[Category:TODO]] + +Caution: Anope with version 2.0.3 has some issues with gcc6. If you start encountering segmentation faults with Anope, sign in to [[irc://anope.org#anope The Anope support IRC]]. Script a run of "sudo -u ircd gdb /usr/bin/services core". Enter "r " and when it crashes run "bt full". Quit out of everything and pastebin the file. Provide this to the support staff. + +Anope Services' NickServ authentication can be linked to [[Sora|AniNIX::Sora]] for unified credentials.[[Category:LDAP]] + +### Service entities +The following entities can be messaged personally (PM'ed) for help with "/msg help + + +[[Category:Public_Service]] +* NickServ will manage IRC nicknames. +* HostServ will manage IRC virtual hosts, to mask IP's. +* ChanServ will manage IRC channels -- new channels can be registered on the network here. +* MemoServ will manage IRC memos (short text-message-like messages between users). + +# Available Clients +You will need to use your own client. All IRC clients will connect to the service by providing the following information: +* Host: aninix.net +* Port: 6697 +* The client should accept invalid certificates. +* The client should automatically join the #lobby channel. +* The client should provide a nickname and NickServ password that the user intends to use. + +### Clients by OS +Some example clients can be found here. +* Linux hosts are strongly recommended to use [https://wiki.archlinux.org/index.php/Weechat weechat] inside [https://wiki.archlinux.org/index.php/Tmux tmux] with the [https://weechat.org/themes/source/crym.theme.html/ crym theme], though a Hexchat version is also available. +* Windows hosts can connect to this service using [https://hexchat.github.io/ HexChat]. +* Mac hosts can use [http://colloquy.info/downloads.html Colloquy]. +* Android hosts can use [http://www.duckspike.net/andchat/ Andchat]. +* iOS devices should use [http://colloquy.info/downloads.html Colloquy's mobile version]. + +# Equivalents or Competition +Rivals to IRC include other IRC networks like [http://freenode.net Freenode], mail services like [https://inbox.google.com Google Inbox], and other chat systems like Slack, Microsoft Teams, Discord, Snapchat, WhatsApp, etc. We use Discord to provide new users with a Web-only bridge to the IRC network at https://aninix.net/irc/ -- [[IRC/Discord Bridge|documentation for our Discord hosting]] is also available.. + +# Additional Reference +{{:IRC/Commands and Modes}} + +### Helpful Reading + +# Additional Reference diff --git a/roles/IRC/tasks/main.yml b/roles/IRC/tasks/main.yml new file mode 100644 index 0000000..28728aa --- /dev/null +++ b/roles/IRC/tasks/main.yml @@ -0,0 +1,19 @@ +--- + + - name: IRC packages + become: yes + package: + name: + - inspircd + - anope + - TheRaven + + - name: KiwiIRC Web Front + become: yes + git: + repo: https://github.com/prawnsalad/KiwiIRC.git + dest: /usr/local/src/KiwiIRC + + + + diff --git a/roles/Nazara/tasks/main.yml b/roles/Nazara/tasks/main.yml new file mode 100644 index 0000000..a171b7f --- /dev/null +++ b/roles/Nazara/tasks/main.yml @@ -0,0 +1,7 @@ +--- + + - name: Nazara packages + become: yes + package: + name: + - pi-hole diff --git a/roles/SSH/README.md b/roles/SSH/README.md new file mode 100644 index 0000000..657200d --- /dev/null +++ b/roles/SSH/README.md @@ -0,0 +1,18 @@ +Remote access is important in the AniNIX, and so we support the use of the [https://wiki.archlinux.org/index.php/Secure_Shell OpenSSH] protocol via [[ShadowArch]] to supporting hosts. + +# Etymology +SSH is named for the protocol on which it's built. + +# Relevant Files and Software +Most of this service's configuration lives in [file:///etc/ssh/sshd_config sshd_config]. This includes match statements on what groups are allowed to connect, allowed protocols, and somewhat importantly the ForceCommand directives that hold certain users captive to specific operations. + +VNC and X11 forwarding can be used over SSH to allow graphical clients. X11 forwarding without SSH compression is generally slower. To allow VNC, log in over SSH and forward remote port 5901 to localhost port 5901. Start the VNC server on the remote, and use a VNC viewer like tightVNC portable to view the remote desktop. + +# Available Clients +* Windows users should use [http://www.putty.org/ PuTTY]. The AniNIX considers this important enough that a copy of PuTTY is mirrored in [https://aninix.net/wolfpack/ WolfPack].[[Category:CachedClient]] +* Mac has a native client in their Terminal application. +* Linux users can install [https://wiki.archlinux.org/index.php/Secure_Shell openssh]. +* Android users can use [https://serverauditor.com/ Server Auditor]. +}} +[[Category:Public_Service]] +[[Category:LDAP]] \ No newline at end of file diff --git a/roles/SSH/files/ssh_config b/roles/SSH/files/ssh_config new file mode 100644 index 0000000..f2d9638 --- /dev/null +++ b/roles/SSH/files/ssh_config @@ -0,0 +1,50 @@ +# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $ + +# This is the ssh client system-wide configuration file. See +# ssh_config(5) for more information. This file provides defaults for +# users, and the values can be changed in per-user configuration files +# or on the command line. + +# Configuration data is parsed as follows: +# 1. command line options +# 2. user-specific file +# 3. system-wide file +# Any configuration value is only changed the first time it is set. +# Thus, host-specific definitions should be at the beginning of the +# configuration file, and defaults at the end. + +# Site-wide defaults for some commonly used options. For a comprehensive +# list of available options, their meanings and defaults, please see the +# ssh_config(5) man page. + +# Host * +# ForwardAgent no +ForwardX11 yes +ForwardX11Trusted yes +# RhostsRSAAuthentication no +# RSAAuthentication yes +# PasswordAuthentication yes +# HostbasedAuthentication no +# GSSAPIAuthentication no +# GSSAPIDelegateCredentials no +# BatchMode no +# CheckHostIP yes +# AddressFamily any +# ConnectTimeout 0 +# StrictHostKeyChecking ask +# IdentityFile ~/.ssh/identity +# IdentityFile ~/.ssh/id_rsa +# IdentityFile ~/.ssh/id_dsa +# Port 22 +# Protocol 2,1 +# Cipher 3des +# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc +# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160 +# EscapeChar ~ +# Tunnel no +# TunnelDevice any:any +# PermitLocalCommand no +# VisualHostKey no +# ProxyCommand ssh -q -W %h:%p gateway.example.com +UseRoaming no +# fix for CVE-2016-0777 diff --git a/roles/SSH/files/sshd_config b/roles/SSH/files/sshd_config new file mode 100644 index 0000000..bbb5a21 --- /dev/null +++ b/roles/SSH/files/sshd_config @@ -0,0 +1,59 @@ +### AniNIX::SSH \\ Basic configuration for listening daemon ### + +# Daemon spec # +Port 22 +ListenAddress 0.0.0.0 +PrintMotd yes +PrintLastLog yes +StrictModes yes +Protocol 2 +ChrootDirectory none +# DSA and ECDSA are untrusted for vulnerabilites and backdoors. https://wiki.archlinux.org/index.php/SSH_keys +# RSA and ED25519 are stable. +HostKey /etc/ssh/ssh_host_rsa_key +HostKey /etc/ssh/ssh_host_ed25519_key + +# Network Performance # +Compression yes +ClientAliveInterval 5 +ClientAliveCountMax 3 + +# Forwarding options # +AllowTcpForwarding no +PermitTunnel no +AllowAgentForwarding no +X11Forwarding no +X11DisplayOffset 10 +X11UseLocalhost no +GatewayPorts no + +# Override default of no subsystems to allow SFTP # +Subsystem sftp /usr/lib/ssh/sftp-server + +# Authentication # +PubkeyAuthentication yes +AuthorizedKeysFile .ssh/authorized_keys +PasswordAuthentication yes +UsePAM yes +ChallengeResponseAuthentication no +HostbasedAuthentication no +KerberosAuthentication no +GSSAPIAuthentication no +DenyGroups [^ssh-allow] +AllowGroups ssh-allow +PermitRootLogin no +PermitEmptyPasswords no + +## Access Controls ### +Match Group ssh-forward + AllowTcpForwarding yes + PermitTunnel yes + AllowAgentForwarding yes + X11Forwarding yes + +Match Group sftp-home-jail + ForceCommand internal-sftp #/usr/lib/ssh/sftp-server + ChrootDirectory /home # Lock the user in their home directory + +Match User crypto + ForceCommand /usr/local/bin/captivecrypto diff --git a/roles/SSH/tasks/main.yml b/roles/SSH/tasks/main.yml new file mode 100644 index 0000000..44586da --- /dev/null +++ b/roles/SSH/tasks/main.yml @@ -0,0 +1,21 @@ +--- + + - name: SSH + become: yes + package: + name: + - bash + - sudo + + - name: SSH Config + become: yes + copy: + src: sshd_config + dest: /etc/ssh/ssh_config + + - name: SSHD Config + become: yes + copy: + src: sshd_config + dest: /etc/ssh/sshd_config + diff --git a/roles/SSL/tasks/main.yml b/roles/SSL/tasks/main.yml new file mode 100644 index 0000000..1e78c34 --- /dev/null +++ b/roles/SSL/tasks/main.yml @@ -0,0 +1,8 @@ +--- + + - name: SSL packages + become: yes + package: + name: + - certbot + - openssl diff --git a/roles/Sharingan-Data/tasks/main.yml b/roles/Sharingan-Data/tasks/main.yml new file mode 100644 index 0000000..6c431b7 --- /dev/null +++ b/roles/Sharingan-Data/tasks/main.yml @@ -0,0 +1,6 @@ +--- + name: Sharingan data filers + become: yes + package: + name: + - syslog-ng diff --git a/roles/Sharingan-IDS/tasks/main.yml b/roles/Sharingan-IDS/tasks/main.yml new file mode 100644 index 0000000..ef33230 --- /dev/null +++ b/roles/Sharingan-IDS/tasks/main.yml @@ -0,0 +1,10 @@ +--- + name: Sharingan IDS/IPS Packages + become: yes + package: + name: + - clamav + - suricata + - oinkmaster + - sshguard + - ossec-local diff --git a/roles/Sharingan/README.md b/roles/Sharingan/README.md new file mode 100644 index 0000000..c6df83b --- /dev/null +++ b/roles/Sharingan/README.md @@ -0,0 +1,37 @@ +Sharingan is the monitoring and blue-team solution for the AniNIX. It is responsible for monitoring and alarming on a wide array of events, from dev-ops to cybersecurity. + +# Etymology +Sharingan is named after the mythical technique from the Naruto anime series. Sharingan confers deep insight abilities to its user, and our implementation of it will do the same for our administrators' domains. + +# Relevant Files and Software + +We use Graylog on a dedicated VM to aggregate results. By default, all servers in a datacenter should send journald via syslog to `sharingan.$datacenter.aninix.net`. + +## Syslog-ng + +We use a lot of services in the AniNIX ecosystem -- some create files, some pipe output, etc. Syslog-ng then picks these up and files them off to graylog over 514/udp/syslog. + +## Journald + +ArchLinux and most systemd-based Linux distributions use journald to track system log files. + +## Suricata + +Suricata generates a file, [fast.log](file:///var/log/suricata/fast.log), containing threat intelligence about network threats. We place this on the Core web front-end to detect incoming assaults on our applications. + +## SSHGuard + +## ClamAV + +## OSSEC + +TODO + +## Monit + +# Available Clients +See [[WebServer#Available Clients|AniNIX::Webserver's client list]]. + +# Equivalents or Competition + +Various monitoring SaaS vendors are available, including Nagios, OP5, PagerDuty, etc. A variety of paid cybersecurity vendors are also on the market, particularly contract firms. Data aggregation is also oft used via the ElasticStack for a number of use-cases. We chose Graylog because it unifies these funtions for what we care about -- alarming on actionable events, whether they are malicious or accidental. diff --git a/roles/Sharingan/tasks/main.yml b/roles/Sharingan/tasks/main.yml new file mode 100644 index 0000000..ca2f5c4 --- /dev/null +++ b/roles/Sharingan/tasks/main.yml @@ -0,0 +1,11 @@ +--- + - name: Sharingan packages + become: yes + package: + name: + - openvas + - greenbone-security-assistant + - elasticsearch6 + - mongodb + - graylog + diff --git a/roles/Sora/README.md b/roles/Sora/README.md new file mode 100644 index 0000000..4d6458d --- /dev/null +++ b/roles/Sora/README.md @@ -0,0 +1,134 @@ +Sora is the [https://en.wikipedia.org/wiki/LDAP LDAP]-enabled central crendential store of the AniNIX -- end users will have accounts here. + +# Etymology=Sora was the name of a pivotal character in the Kingdom of Hearts series. As Sora holds the "keys to the kingdom", the name fit. + +# Relevant Files and Software +Most of the configuration initially is handled by the [https://aninix.net/foundation/ConfigPackages ConfigPackages'] Sora Makefile. + +We use [file:///etc/openldap/users.d a users.d] folder to hold the default user definitions. uidNumber should generally start from 10000 and the .ldif files should never be deleted to track the maximum uidNumber. + +# Available Clients +See [[:Category:LDAP]] for more information on the services that are clients of Sora. + +# Equivalents or Competition +Both [[:Category:Google|Google]] and Facebook offer distributed authentication systems. Google in particular is a good equivalent, as some of the services used by this network rely on its authentication for various products it provides internally. + +The AniNIX is not presently set up or planning to do distributed authentication. +}} +# Authorizing Other Services by Sora +## [[ShadowArch]] OS Authentication +You will need nss-pam-ldap as package installed. You will need to edit /etc/pam.d/su, /etc/pam.d/su-l, /etc/pam.d/system-auth, and /etc/nslcd.conf to match [https://eng.ucmerced.edu/soe/computing/services/ssh-based-service/ldap-ssh-access this link] and [https://wiki.archlinux.org/index.php/LDAP_authentication the Arch Wiki]. +## [[Windows]] OS Authentication +We recommend the [https://pgina.org/ pGina] package -- this is a very smooth client. +## [[SSH]] +Edit /etc/ssh/sshd_config to allow PasswordAuthentication and PAM. This assumes the OS authentication is set up. + +We recommend adding a passwdchange OS group on the external-facing SSH host and set up a ForceCommand around /usr/bin/passwd for users in that group. This allows you to enable centralized password changes from outside the command line for subscribing clients and then disable password changes in individual services. +## [[IRC|IRCServices]] +You will need to enable m_ldap and m_ldap_authentication in [file:///etc/anope/modules.aninix.conf the modules conf file]. The modules conf has the necessary parameters waiting to be filled in. We recommend updating the search_filter to "(&(!(shadowLastChange=0))(&(uid=%account)(objectClass=%object_class)))". This will prevent users from using a password reset by an administrator. + +When you enable LDAP for IRCServices, we would recommend disabling email changes in m_ldap_authentication and disabling account creation in the NickServ configuration. Do not disable registration in m_ldap_authentication. This ensures that account provisioning is done by LDAP and users can group as necessary. Moreover, disable password changes by removing the NickServ set/*pass directives. +## [[Singularity]] +You'll need to update your plugins line in [file:///usr/share/webapps/tt-rss/config.php the config file] and add some parameters. Note: you'll be removing the auth_internal module, but you'll have to add it at least once to promote an LDAP user to admin. + +
+define('PLUGINS', 'auth_remote, note, updater, auth_ldap');
+define('LDAP_AUTH_SERVER_URI', 'ldap://localhost:389/');
+define('LDAP_AUTH_USETLS', FALSE); // Enable TLS Support for ldaps://
+define('LDAP_AUTH_ALLOW_UNTRUSTED_CERT', TRUE); // Allows untrusted certificate
+define('LDAP_AUTH_BINDDN', 'uid=binduser,ou=People,dc=aninix,dc=net');
+define('LDAP_AUTH_BINDPW', 'secret');
+define('LDAP_AUTH_BASEDN', 'ou=People,dc=aninix,dc=net');
+define('LDAP_AUTH_ANONYMOUSBEFOREBIND', FALSE);
+define('LDAP_AUTH_SEARCHFILTER', 'uid=???');
+
+## [[Wiki]] +Wiki is the most complicated to add with its multiple domain support, but the following snippet can be modified for a single domain. You'll need to comment out the fourth line at least once after logging in an LDAP user to promote that user to administrator. + +
+1.  LDAP Modules
+require_once( "extensions/LdapAuthentication/LdapAuthentication.php" );
+require_once( "includes/AuthPlugin.php");
+$wgAuth = new LdapAuthenticationPlugin();
+
+1. LDAP Debugging
+$wgLDAPDebug = 0;
+$wgDebugLogGroups["ldap"] = "$IP/debug.log" ;
+
+1.  LDAP Connection info
+$wgLDAPUseLocal = false;
+$wgLDAPDomainNames = array( 'aninix.net', );
+$wgLDAPServerNames = array( 'aninix.net' => 'localhost', );
+$wgLDAPEncryptionType = array( 'aninix.net' => 'clear',
+                               #'aninix.net' => 'tls',
+);
+1. $wgLDAPOptions = array( 'aninix.net' => array( LDAP_OPT_DEREF, 0 ), );
+$wgLDAPPort = array( 'aninix.net' => 389, );
+$wgLDAPProxyAgent = array( 'aninix.net' => 'uid=binduser,ou=People,dc=aninix,dc=net', );
+$wgLDAPProxyAgentPassword = array( 'aninix.net' => 'secret', );
+$wgLDAPSearchAttributes = array( 'aninix.net' => 'uid', );
+$wgLDAPBaseDNs = array( 'aninix.net' => 'dc=aninix,dc=net', );
+$wgLDAPGroupBaseDNs = array( 'aninix.net' => 'ou=Group,dc=aninix,dc=net', );
+$wgLDAPUserBaseDNs = array( 'aninix.net' => 'ou=People,dc=aninix,dc=net', );
+$wgLDAPAddLDAPUsers = array( 'aninix.net' => false, );
+$wgLDAPUpdateLDAP = array( 'aninix.net' => false, );
+$wgLDAPPreferences = array( 'aninix.net' => array( 'email' => 'mail','realname' => 'cn','nickname' => 'uid'), );
+
+1.  LDAP Access Only by Group Membership -- requires the memberOf overlay in Sora
+1. $wgLDAPGroupUseFullDN = array( "aninix.net"=>false );
+1. $wgLDAPGroupObjectclass = array( "aninix.net"=>"posixgroup" );
+1. $wgLDAPGroupAttribute = array( "aninix.net"=>"memberuid" );
+1. $wgLDAPGroupSearchNestedGroups = array( "aninix.net"=>false );
+1. $wgLDAPGroupNameAttribute = array( "aninix.net"=>"cn" );
+1. $wgLDAPRequiredGroups = array( "aninix.net"=>array("cn=wiki,ou=Group,dc=aninix,dc=net"));
+
+1. Disable password changes.
+$wgHooks['UserLoginForm'][] = 'lfChangeLoginPage';
+function lfChangeLoginPage( &$template ) {
+    $template->set('canreset',false); // removes default reset password link
+    $template->set('resetlink',false);
+    // Use the following line to show your own 'reset password' link above the login fields
+    $template->set('link',"Forgot your password?");
+    return true;
+ }
+// Disallow password reset on password reset page
+$wgHooks['UserLoginMailPassword'][] = 'MailPasswordIsAllowed';
+function MailPasswordIsAllowed ( $username, $error ) {
+    $error = wfMsg( 'resetpass_forbidden' );
+
+    return false;
+}
+$wgHooks['PrefsPasswordAudit'][] = 'ChangePasswordIsAllowed';
+function ChangePasswordIsAllowed ( $user ) {
+    throw new PasswordError( wfMsg( 'resetpass_forbidden' ));
+    return true;
+}
+$wgHooks['GetPreferences'][] = 'RemovePasswordChangeLink';
+function RemovePasswordChangeLink ( $user, &$preferences ) {
+    unset($preferences['password']);
+    return true;
+}
+
+# Making Changes +Ldapmodify will allow admins to change parts of Sora. Most user attributes can be updated like below. +
+dn: uid=testuser,ou=People,dc=aninix,dc=net
+changetype: modify
+replace: mail
+mail: blar@test.local
+
+
+ +Some properties are more intrinsic to the user object and require special handling. +
+dn: uid=testuser1,ou=People,dc=aninix,dc=net
+changetype: modrdn
+newrdn: uid=testuser2
+deleteoldrdn: 1
+modifying rdn of entry "uid=testuser2,ou=People,dc=aninix,dc=net"
+
+
+ + +[[Category:Security]] +[[Category:LDAP]] \ No newline at end of file diff --git a/roles/Sora/tasks/main.yml b/roles/Sora/tasks/main.yml new file mode 100644 index 0000000..ecf73fa --- /dev/null +++ b/roles/Sora/tasks/main.yml @@ -0,0 +1,7 @@ +--- + - name: Sora packages + become: yes + package: + name: + - openldap + diff --git a/roles/Uptime/tasks/main.yml b/roles/Uptime/tasks/main.yml new file mode 100644 index 0000000..98a7f26 --- /dev/null +++ b/roles/Uptime/tasks/main.yml @@ -0,0 +1,8 @@ +--- + - name: Uptime + command: uptime + register: uptime_output + + - name: Show output + debug: + msg: "{{ uptime_output.stdout_lines }}" diff --git a/roles/Vanik/tasks/main.yml b/roles/Vanik/tasks/main.yml new file mode 100644 index 0000000..0d7e6cf --- /dev/null +++ b/roles/Vanik/tasks/main.yml @@ -0,0 +1,12 @@ +--- + + - command: ./scripts/generate-dhcp.py + delegate_to: localhost + run_once: true + name: Generate DHCP leases. + + - command: ./scripts/generate-dns.py + delegate_to: localhost + run_once: true + name: Generate DNS entries + diff --git a/roles/WebServer/README.md b/roles/WebServer/README.md new file mode 100644 index 0000000..3acdf1c --- /dev/null +++ b/roles/WebServer/README.md @@ -0,0 +1,31 @@ +Having some information be publicly accessible is useful to the network -- it's how we can be available to new people. Because HTTPS is the protocol of choice today, the WebServer is our vector. + +# Etymology +The WebServer serves content on the Web -- its name is simple to match the function. + +# Relevant Files and Software +Configuration files live in [file:///etc/lighttpd/lighttpd.conf lighttpd.conf], including ciphersuites, URI redirection, and pathing. It can be validated with the following. +
lighttpd -t -f /etc/lighttpd/lighttpd.conf
+ +Most notably, our lighttpd.conf is set to set specific headers to prevent XSS vulnerabilities. We allow the plaintext listener for a better user experience, but we restrict scripts and style resources from loading from plaintext links via Content-Security-Policy. Our X-Frame options are also set to be restrictive against XSS vulnerabilities. We pin the [[Category:SSL|Let's Encrypt]] sha-256 public key signature, and require strict transport security. + +Data files live in [file:///srv/http/ the http directory]. Each domain is virtually hosted by the AniNIX and pathing is set up in configuration. Sites in the WebServer are designed to be as sparse and lightweight as possible for rapidly disseminating information; this comes at a cost of beauty. + +The WebServer uses six PHP child processes to handle the processing of pages. Both the WebServer and [[Wiki]] are built on PHP engines to reduce code sprawl and edit times. We will install a custom php.ini to handle things like disabling expose_php and configuring open_basedir. + +**Please note:** We offer a redirect on www.aninix.net and http://aninix.net:80/ only as a legacy convenience as browsers do not yet support 443 by default -- no data is transmitted on these. When the webhosting community acknowledges the death of the empty www. subdomain and the necessity of encryption, we will drop these. However, for usability, we include them for now. + +# Available Clients +* Windows users should use [http://google.com/chrome/browser/desktop/ Chrome] or Firefox. A copy of Chrome is stored in [https://aninix.net/wolfpack WolfPack]. + * Privacy-conscious users may be interested in [http://www.seamonkey-project.org/ Seamonkey], also stored in WolfPack. This browser includes mail and IRC clients and can be installed on a [[Holocron|flash drive]]. It can be set to silently purge privacy information on closing, and it is lighter on the OS. +* [[ShadowArch]] users should use Seamonkey; chromium can be used to support custom Chrome extensions and bleeding-edge services, like Pushbullet or Netflix. +[[Category:CachedClient]] +* Mac users should use Safari or Chrome. +* Mobile users should use the built-in browser. + +# Equivalents or Competition +Hosting services like [https://godaddy.com GoDaddy] and [http://freehostia.com/ FreeHostia] will provide hosting services for web pages. Content management can be done with systems like WordPress. +}} + +[[Category:Public_Service]] +[[Category:SSL]] \ No newline at end of file diff --git a/roles/WebServer/files/conf.d/aaa_default.conf b/roles/WebServer/files/conf.d/aaa_default.conf new file mode 100644 index 0000000..81b897b --- /dev/null +++ b/roles/WebServer/files/conf.d/aaa_default.conf @@ -0,0 +1,17 @@ +server { + #listen 443 ssl http2; + listen 444 ssl http2; + server_name default_server; + + include sec.conf; + include default.csp.conf; + + location / + { + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://127.0.0.1:3000; + } +} diff --git a/roles/WebServer/files/conf.d/adhan.conf b/roles/WebServer/files/conf.d/adhan.conf new file mode 100644 index 0000000..78cb58c --- /dev/null +++ b/roles/WebServer/files/conf.d/adhan.conf @@ -0,0 +1,12 @@ +server { + listen 444 ssl http2; + server_name adhan.aninix.net; + + include sec.conf; + include default.csp.conf; + + location / + { + root /srv/adhan/; + } +} diff --git a/roles/WebServer/files/conf.d/graylog.conf b/roles/WebServer/files/conf.d/graylog.conf new file mode 100644 index 0000000..293947b --- /dev/null +++ b/roles/WebServer/files/conf.d/graylog.conf @@ -0,0 +1,18 @@ +server { + #listen 443 ssl http2; + listen 444 ssl http2; + server_name sharingan.aninix.net; + + include sec.conf; + # include default.csp.conf; + + location / + { + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Graylog-Server-URL https://$server_name/; + proxy_pass http://10.0.1.5:9000; + } +} diff --git a/roles/WebServer/files/conf.d/lykos-wiki.conf b/roles/WebServer/files/conf.d/lykos-wiki.conf new file mode 100644 index 0000000..4efb520 --- /dev/null +++ b/roles/WebServer/files/conf.d/lykos-wiki.conf @@ -0,0 +1,46 @@ +server { + listen 444 ssl; + server_name lykos.aninix.net; + + include sec.conf; + include default.csp.conf; + + root /usr/share/webapps/; + + location ~ ^/$ { + return 302 https://lykos.aninix.net:444/lykos-wiki/Main_Page; + } + + location ~ ^/lykos-wiki/ { + index /mediawiki/index.php; + try_files $uri $uri/ @mediawiki; + } + location @mediawiki { + rewrite ^/lykos-wiki/(.*)$ /mediawiki/index.php?title=$1; + } + location ~ \.php?$ { + fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; + fastcgi_index /mediawiki/index.php; + try_files $uri @mediawiki; + } + location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { + try_files $uri /lykos-wiki/index.php; + expires max; + log_not_found off; + } +# Restrictions based on the .htaccess files + location ~ ^/lykos-wiki/(cache|includes|maintenance|languages|serialized|tests|images/deleted)/ { + deny all; + } + location ~ ^/lykos-wiki/(bin|docs|extensions|includes|maintenance|mw-config|resources|serialized|tests)/ { + internal; + } + location ^~ /images/ { + try_files $uri /index.php; + } + location ~ /\. { + access_log off; + log_not_found off; + deny all; + } +} diff --git a/roles/WebServer/files/conf.d/password.conf b/roles/WebServer/files/conf.d/password.conf new file mode 100644 index 0000000..d157fa7 --- /dev/null +++ b/roles/WebServer/files/conf.d/password.conf @@ -0,0 +1,12 @@ +server { + listen 444 ssl http2; + server_name password.aninix.net; + + include sec.conf; + include default.csp.conf; + + location / + { + root /usr/share/webapps/self-service-password/; + } +} diff --git a/roles/WebServer/files/conf.d/test b/roles/WebServer/files/conf.d/test new file mode 100644 index 0000000..e69de29 diff --git a/roles/WebServer/files/nginx.conf b/roles/WebServer/files/nginx.conf new file mode 100644 index 0000000..f9d5909 --- /dev/null +++ b/roles/WebServer/files/nginx.conf @@ -0,0 +1,34 @@ +user http; +worker_processes 4; + +# Logs +error_log logs/error.log; +error_log logs/error.log notice; +error_log logs/error.log info; + +events { + worker_connections 1024; +} + + +http { + + include mime.types; + include fastcgi.conf; + default_type application/octet-stream; + + server_tokens off; + sendfile on; + keepalive_timeout 65; + gzip on; + + # Redirect all HTTP to HTTPS + server { + listen 81 default_server; + listen [::]:81 default_server; + server_name _; + return 301 https://$host$request_uri; + } + + include ../conf.d/*.conf; +} diff --git a/roles/WebServer/tasks/main.yml b/roles/WebServer/tasks/main.yml new file mode 100644 index 0000000..997e636 --- /dev/null +++ b/roles/WebServer/tasks/main.yml @@ -0,0 +1,37 @@ +--- + - name: Install openresty + become: yes + package: + name: openresty + state: present + + + - name: Copy conf.d + become: yes + copy: + src: conf.d + dest: /opt/openresty/nginx/ + owner: http + group: http + mode: 0660 + directory_mode: 0770 + + - name: Copy main config + become: yes + copy: + src: nginx.conf + dest: /opt/openresty/nginx/conf/nginx.conf + owner: http + group: http + mode: 0660 + validate: "/opt/openresty/nginx/sbin/nginx -t -c %s" + + + # TODO when openresty is ready to go, populate /usr/lib/systemd/system/webserver.service from /usr/lib/systemd/system/openresty.service + + - name: Ensure service is started + become: yes + service: + name: openresty + enabled: yes + state: restarted diff --git a/roles/Yggdrasil/README.md b/roles/Yggdrasil/README.md new file mode 100644 index 0000000..115374d --- /dev/null +++ b/roles/Yggdrasil/README.md @@ -0,0 +1,58 @@ +The AniNIX aims to share information. Yggdrasil holds the many worlds of information available. See [[Yggdrasil#Available Clients|Available Clients]] below for ways to access the system. + +# Etymology +The most commonly accepted etymology of the name is ygg "terrible" + drasil "steed". While the name means the "terrible steed", it is usually taken to mean the "steed of the terrible one", with Yggr the epithet of the god Odin. In other words, Odin's horse, referring to the nine nights he is said to have spent hanging from the tree, or "riding the gallows", in order to acquire knowledge of the runic alphabet. + +The gallows are sometimes described in Old Norse poetry as the "horse of the hanged." In the case of "terrible steed", the association with Odin may be secondary, and any number of riders possible. A third interpretation, with etymological difficulties, is "yew-column", associating the tree with the Eihwaz rune. + +Fjölsvinnsmál, a poem in the Poetic Edda, refers to the World Tree as Mimameid (Old Norse: Mímameiðr, "Mímir's tree" ). The tree is also probably identical to Laerad (Old Norse: Læraðr) a tree whose leaves and branches reach down to the roof of Valhalla and provide food for the goat Heidrun (Old Norse: Heiðrún) and the stag Eikthyrnir (Old Norse: Eikþyrnir). + +## The Nine Worlds +The Yggdrasil tree is home to the Nine Worlds in Norse Cosmology. The worlds are: +In the north: Niflheim +In the east: Jotunheim +In the south: Musspelheim +In the west: Vanaheim +In the center: Midgard +Above: Alfheim and Asgard +Below: Svartalfheim and Helheim + +## Residents +The World Tree is inhabited by several animals, the Nίðhӧggr, pet dragon of the goddess Hel which chews the roots of the tree which bind it, Veðrfӧlnir the rooster, who will crow when Ragnarok occurs, Ratatӧsk the squirrel, who carries messages of hate between the eagle and the Nίðhӧggr. This eagle, who is not named, is said to have knowledge of many things, and on its head sits Veðrfӧlnir. The significance of Veðrfӧlnir is unclear but John Lindow suggests that it may represent a higher faculty of wisdom, possibly sent out to acquire knowledge in a similar manner as Odin's ravens Hugin and Munin. + +The original Norn was undoubtedly Urd, a word which can be translated to mean "Fate". The Well of Urd, which was situated at the base of the great cosmic tree Yggdrasil, is named after this Norn. The two additional Norns that are known by name are Verdandi ("Present" [or "Necessity" in some versions]) and Skuld ("Future" [or "Being" in some versions]). All three Norns live at the Well of Urd in Asgard. According to Norse mythology, nothing lasts forever, and even the great Yggdrasil has been said to decay one day. The Norns try to stop or slow this process by pouring mud and water from the Well of Urd over its branches. The magical liquid stops the decaying process for a short time. + +## Relevance to the Service + +Yggdrasil is a knowledge repository for the AniNIX -- it literally "holds the worlds" for the network's data content. + + +# Relevant Files and Software +All configuration is cached inside the service -- we log to [file:///var/lib/emby/logs Emby's logs directory] and data lives in [file:///var/lib/emby /var/lib/emby]. You can build it using the [https://aninix.net/foundation/ConfigPackages ConfigPackages], which will handle the initial directory installation along with an emby-server service. + +To keep a consistent color scheme, we add the following under the Emby Server Dashboard > Advanced > Branding. This does not help mobile, but it does make a significant help to computer use. +
+/* https://benzuser.github.io/Emby-Web-Dark-Themes-CSS/ */
+@import url('https://rawgit.com/BenZuser/Emby-Web-Dark-Themes-CSS/master/RED/theme.css');
+
+ +LDAP in Emby world is controlled by a dotnet plugin. Bind DN, search filters, and initial user setup are controlled within the plugin from the server admin panel; the plugin can be pulled from the plugin catalog inside Emby. Usage of it is dependent on an Emby premiere membership -- failure to have such will result in "System.Exception: Emby Premiere required for LDAP" messages in the logs. However, this can sometimes be a false positive if preceded by lines of "Error Plugin: Error checking registration status of ldapfeature" -- the latter will be caused by a [https://emby.media/community/index.php?/topic/59531-external-ssl-connections-crashing/page-3#entry589538 documented issue with dotnet core] that can be resolved by "sudo chmod a+r /etc/ssl/certs/*". + + +# Available Clients +### Music, Pictures, and Video +* You can go to [https://aninix.net/yggdrasil the web-app] for a web-accessible view of the service. +* Android users can use a specific [https://play.google.com/store/apps/details?id=com.mb.android app]. +### Books and Other Media +* Windows users can use [https://winscp.net/eng/download.php WinSCP]. The AniNIX contains a cached copy of this in [https://aninix.net/wolfpack/ WolfPack].[[Category:CachedClient]] +* Mac users have a native client. +* Linux users should install the openssh client -- see [[SSH#Available clients]] for details. +* Android should use [https://play.google.com/store/apps/details?id=turbo.client Turbo Client]. + +# Equivalents or Competition +Rivals include [https://pinterest.com Pinterest], [https://soundcloud.com Soundcloud], [https://netflix.com NetFlix], [https://smile.amazon.com Amazon Kindle], [https://play.google.com Google Play], and [https://hulu.com Hulu]. +}} +[[Category:Public_Service]] +[[Category:SSL]] +[[Category:Emby]] +[[Category:LDAP]] \ No newline at end of file diff --git a/roles/Yggdrasil/tasks/main.yml b/roles/Yggdrasil/tasks/main.yml new file mode 100644 index 0000000..0214172 --- /dev/null +++ b/roles/Yggdrasil/tasks/main.yml @@ -0,0 +1,19 @@ +--- + + - name: Yggdrasil packages + become: yes + package: + name: + - emby-server + + + + - name: Yggdrasil directory + become: yes + file: + path: /srv/yggdrasil + state: directory + owner: http + group: http + mode: 0750 + diff --git a/roles/basics/README.md b/roles/basics/README.md new file mode 100644 index 0000000..9cc1890 --- /dev/null +++ b/roles/basics/README.md @@ -0,0 +1,7 @@ +This role is defined to handle basic system setup tasks. + +# Scope +* Setting the hostname +* Installing [/AniNIX/ShadowArch] customizations +* Managing passwords +* Setting initial sudo permissions. diff --git a/roles/basics/files/pacman.conf b/roles/basics/files/pacman.conf new file mode 100644 index 0000000..6b5642a --- /dev/null +++ b/roles/basics/files/pacman.conf @@ -0,0 +1,109 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +#HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -C - -f %u > %o +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +CleanMethod = KeepCurrent +#UseDelta = 0.7 +Architecture = auto + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +# IgnorePkg = postgresql postgresql-libs +# IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +Color +ILoveCandy +#TotalDownload +CheckSpace +#VerbosePkgLists + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +#[testing] +#Include = /etc/pacman.d/mirrorlist + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +#[community-testing] +#Include = /etc/pacman.d/mirrorlist + +[community] +Include = /etc/pacman.d/mirrorlist + +# If you want to run 32 bit applications on your x86_64 system, +# enable the multilib repositories as required here. + +#[multilib-testing] +#Include = /etc/pacman.d/mirrorlist + +[multilib] +Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs + +[AniNIX] +SigLevel = Required DatabaseOptional +Server = https://maat.aninix.net/ + +[aur] +SigLevel = Required DatabaseOptional +Server = https://maat.aninix.net/aur/ diff --git a/roles/basics/tasks/main.yml b/roles/basics/tasks/main.yml new file mode 100644 index 0000000..93884ad --- /dev/null +++ b/roles/basics/tasks/main.yml @@ -0,0 +1,120 @@ +--- +### +# This role installs the basic package and host setup for AniNIX operations. +# +# +# + - name: Set up AniNIX-specific repository + become: yes + file: + path: /opt/aninix + state: directory + + - name: Verify GPG keys + ignore_errors: yes + become: yes + command: + cmd: gpg --homedir /etc/pacman.d/gnupg --list-key 1CC1E3F4ED06F296 + register: gpg_verify + when: ansible_os_family == "Archlinux" + + - name: Install GPG keys + become: yes + command: + cmd: /bin/bash -l -c 'pacman-key --recv-key 1CC1E3F4ED06F296; pacman-key --finger 1CC1E3F4ED06F296; pacman-key --lsign-key 1CC1E3F4ED06F296;' + when: ansible_os_family == "Archlinux" and gpg_verify.rc != 0 + + - name: Set up pacman.conf + become: yes + blockinfile: + path: /etc/pacman.conf + insertafter: EOF + marker: "# {mark} Ubiqtorate Managed Block" + block: | + [AniNIX] + SigLevel = Required DatabaseOptional + Server = https://maat.aninix.net/ + + [aur] + SigLevel = Required DatabaseOptional + Server = https://maat.aninix.net/aur/ + when: ansible_os_family == "Archlinux" + + - name: Install ShadowArch (ArchLinux) + become: yes + pacman: + name: ShadowArch + state: present + update_cache: yes + when: ansible_os_family == "Archlinux" + + - name: Download ShadowArch (Other) + become: yes + git: + repo: 'https://foundation.aninix.net/AniNIX/ShadowArch' + dest: '/opt/aninix/ShadowArch' + update: yes + when: ansible_os_family != "Archlinux" + + - name: Install ShadowArch (Other) + become: yes + command: + chdir: '/opt/aninix/ShadowArch' + cmd: 'make install' + when: ansible_os_family != "Archlinux" + + - name: Base packages + become: yes + package: + name: + - bash + - sudo + + - name: Set up hostname + become: yes + hostname: + name: "{{ inventory_hostname }}.{{ replica_domain }}" + + - name: Set up /etc/hosts + become: yes + lineinfile: + dest: /etc/hosts + regexp: '^127.0.0.1[ \t]+localhost' + line: "127.0.0.1 localhost localhost.localdomain {{ inventory_hostname }} {{ inventory_hostname }}.{{ replica_domain }}" + state: present + + - name: Identify depriv user + command: + cmd: "bash -c 'getent passwd 1001 | cut -f 1 -d :'" + register: depriv_user + + # This is an AniNIX convention to allow password management by Ansible. + - name: Ensure 1001 has sudo permissions. + become: yes + copy: + dest: /etc/sudoers.d/1001 + content: "{{ depriv_user.stdout }} ALL=(ALL) NOPASSWD: ALL\n" + + - name: Test root password + ignore_errors: yes + register: root_password_test + become: yes + command: id + vars: + ansible_become_method: su + ansible_become_user: root + ansible_become_password: "{{ lookup('vars',inventory_hostname+'_password') }}" + + - name: Define root password + become: yes + when: root_password_test.rc is not defined or root_password_test.rc != 0 + command: + cmd: /bin/bash -l -c "printf '%s\n%s\n' '{{ lookup('vars',inventory_hostname+'_password') }}' '{{ lookup('vars',inventory_hostname+'_password') }}' | passwd" + + + - name: Define depriv password + become: yes + when: root_password_test.rc is not defined or root_password_test.rc != 0 + command: + cmd: /bin/bash -l -c "printf '%s\n%s\n' '{{ lookup('vars',inventory_hostname+'_password') }}' '{{ lookup('vars',inventory_hostname+'_password') }}' | passwd {{ depriv_user.stdout }}" + diff --git a/tests/test_net-detect.py b/tests/test_net-detect.py new file mode 100644 index 0000000..2b250dc --- /dev/null +++ b/tests/test_net-detect.py @@ -0,0 +1,7 @@ +import os +import re +import pytest +from modules import netdetect + +def test_netdetect_usage(): + assert True