commit ff71b8fb7645e0376345c7eeeb55bc99ff9a857e Author: creme Date: Mon Oct 14 22:08:03 2019 +0000 init diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f37b64c --- /dev/null +++ b/Makefile @@ -0,0 +1,117 @@ +BASENAME ?= envs + +PREFIX ?= /usr/local +BINDIR ?= $(PREFIX)/bin + + +YELLOW = $$(tput setaf 226) +GREEN = $$(tput setaf 46) +RED = $$(tput setaf 196) +RESET = $$(tput sgr0) + + +install: + @make bin etc cron fail2ban initd letsencrypt nginx ssh sysctl systemd motd znc + +uninstall: + @make clean +clean: + @printf "$(YELLOW)--- clean -----------------------------------------------\n$(RESET)" + stow -t "$(BINDIR)" -D bin + + stow -t /etc/cron.d -D -d etc cron.d + @rm -fv /etc/inetd.conf /etc/inputrc /etc/nanorc /etc/sudoers + @rm -fv /etc/fail2ban/jail.d/envs.conf + @rm -fv /etc/init.d/S41firewall + @rm -fv /etc/letsencrypt/renewal-hooks/deploy/envs.sh + stow -t /etc/nginx -D -d etc nginx + @rm -fv /etc/ssh/ssh_config /etc/ssh/sshd_config + stow -t /etc/sysctl.d -D -d etc sysctl.d + stow -t /etc/systemd/system -D -d etc/systemd system + stow -t /etc/update-motd.d -D -d etc update-motd.d + + @rm -fv /srv/znc/add_znc_user.sh /srv/znc/newuser.conf.template + + +bin: + @printf "$(GREEN)--- bin ------------------------------------------------\n$(RESET)" + stow -t "$(BINDIR)" bin + +etc: + @printf "$(GREEN)--- etc ------------------------------------------------\n$(RESET)" + @install -m 644 etc/etc/inetd.conf /etc + @install -m 644 etc/etc/inputrc /etc + @install -m 644 etc/etc/nanorc /etc + @install -m 644 etc/etc/sudoers /etc + +cron: + @printf "$(GREEN)--- cron -----------------------------------------------\n$(RESET)" + stow -t /etc/cron.d -d etc cron.d + +fail2ban: + @printf "$(GREEN)--- letsencrypt ----------------------------------------\n$(RESET)" + @install -m 755 etc/fail2ban/jail.d/envs.conf /etc/fail2ban/jail.d/ + +initd: + @printf "$(GREEN)--- init.d ---------------------------------------------\n$(RESET)" + @install -m 755 etc/init.d/S41firewall /etc/init.d/ + +letsencrypt: + @printf "$(GREEN)--- letsencrypt ----------------------------------------\n$(RESET)" + @install -m 755 etc/letsencrypt/renewal-hooks/deploy/envs.sh /etc/letsencrypt/renewal-hooks/deploy/ + +nginx: + @printf "$(GREEN)--- nginx ----------------------------------------------\n$(RESET)" + @rm -rf /etc/nginx/conf.d /etc/nginx/modules-available + stow -t /etc/nginx -d etc nginx + @mkdir /etc/nginx/conf.d /etc/nginx/modules-available + +ssh: + @printf "$(GREEN)--- ssh ------------------------------------------------\n$(RESET)" + @install -m 644 etc/ssh/ssh_config /etc/ssh/ + @install -m 644 etc/ssh/sshd_config /etc/ssh/ + +sysctl: + @printf "$(GREEN)--- sysctl.d -------------------------------------------\n$(RESET)" + stow -t /etc/sysctl.d -d etc sysctl.d + +systemd: + @printf "$(GREEN)--- systemd --------------------------------------------\n$(RESET)" + stow -t /etc/systemd/system -d etc/systemd system + +motd: + @printf "$(GREEN)--- motd -----------------------------------------------\n$(RESET)" + stow -t /etc/update-motd.d -d etc update-motd.d + +znc: + @printf "$(GREEN)--- znc ------------------------------------------------\n$(RESET)" + @install -m 755 srv/znc/add_znc_user.sh /srv/znc + @install -m 644 srv/znc/newuser.conf.template /srv/znc + @chown znc:znc /srv/znc/add_znc_user.sh /srv/znc/newuser.conf.template + + +nuke: + @printf "$(RED)--- nuking existing files ---------------------------------\n$(RESET)" + @rm -fv "$(BINDIR)"/conntrack.sh "$(BINDIR)"/envs_conntracks.sh + @rm -fv "$(BINDIR)"/envs_* "$(BINDIR)"/envs_user_manage "$(BINDIR)"/welcome-email.tmpl "$(BINDIR)"/welcome-readme.tmpl + @rm -fv "$(BINDIR)"/byobu-info "$(BINDIR)"/chat "$(BINDIR)"/dcss "$(BINDIR)"/hole "$(BINDIR)"/idiff "$(BINDIR)"/motd \ + "$(BINDIR)"/online-users "$(BINDIR)"/webirc + + @rm -fv /etc/cron.d/conntrack /etc/cron.d/envs_* /etc/cron.d/backup \ + /etc/cron.d/botany /etc/cron.d/certbot /etc/cron.d/update-blacklist /etc/cron.d/update-blacklist_fail2ban + + @rm -fv /etc/fail2ban/jail.d/envs.conf + @rm -fv /etc/init.d/S41firewall + @rm -fv /etc/letsencrypt/renewal-hooks/deploy/envs.sh + @rm -rfv /etc/nginx/* + @rm -fv /etc/ssh/ssh_config /etc/ssh/sshd_config + @rm -fv /etc/sysctl.d/10-kernel-hardening.conf /etc/sysctl.d/30-lxc-inotify.conf \ + /etc/sysctl.d/fs.conf /etc/sysctl.d/net.conf /etc/sysctl.d/panic.conf /etc/sysctl.d/protect-links.conf + @rm -fv /etc/systemd/system/bbj.service /etc/systemd/system/gopherproxy.service \ + /etc/systemd/system/ifconfigme.service /etc/systemd/system/thelounge.service /etc/systemd/system/znc.service + @rm -fv /etc/update-motd.d/* + + @rm -fv /srv/znc/add_znc_user.sh /srv/znc/newuser.conf.template + + +.PHONY: install clean uninstall nuke bin etc cron fail2ban initd letsencrypt nginx ssh sysctl systemd motd znc diff --git a/README.md b/README.md new file mode 100644 index 0000000..25165ae --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# envs.net - ops diff --git a/bin/av98 b/bin/av98 new file mode 100755 index 0000000..60f844d --- /dev/null +++ b/bin/av98 @@ -0,0 +1,3 @@ +#!/bin/sh + +python3 /opt/services/AV-98/av98.py "$@" diff --git a/bin/byobu-info b/bin/byobu-info new file mode 100755 index 0000000..5ef3cfa --- /dev/null +++ b/bin/byobu-info @@ -0,0 +1,15 @@ +#!/usr/bin/env sh + +/usr/local/bin/motd + +/usr/bin/figlet -f smslant welcome! + +printf "you're in a byobu session\n" +printf "if you're familiar with tmux, continue as normal, but with ctrl-a instead of ctrl-b\n" +printf "if you don't want to this happen by default when you log in, run byobu-disable.\n" +printf 'press shift-f1 for a full list of keybinds\n' +printf 'man byobu for more info\n\n' +printf 'f2 creates a new tab\n' +printf 'f3 and f4 move you between tabs\n' +printf 'f6 disconnects and leaves everything running\n' +printf 'shift-f12 disable/enable byobu f-key bindings\n' diff --git a/bin/chat b/bin/chat new file mode 100755 index 0000000..955d3de --- /dev/null +++ b/bin/chat @@ -0,0 +1,3 @@ +#!/bin/sh + +weechat "$@" diff --git a/bin/conntrack.sh b/bin/conntrack.sh new file mode 100755 index 0000000..a66e9e8 --- /dev/null +++ b/bin/conntrack.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +[[ "$EUID" -ne 0 ]] && printf 'Please run as root!\n' && exit 1 + +f="/var/log/conntrack.log" + +d="$(date)" +n1="$(/sbin/sysctl -a 2>&1 | grep -i 'net.netfilter.nf_conntrack_max')" +n2="$(/sbin/sysctl -a 2>&1 | grep -i 'net.nf_conntrack_max')" +c="$(/sbin/sysctl net.netfilter.nf_conntrack_count)" + +echo "conntrack: $d: $n1, $n2, $c" >> $f + +# +exit 0 diff --git a/bin/dcss b/bin/dcss new file mode 100755 index 0000000..f05fc9c --- /dev/null +++ b/bin/dcss @@ -0,0 +1,11 @@ +#!/bin/sh +set -e + +SOURCEKEY="https://crawl.tildeverse.org/dcss.key" +MYKEY="${HOME}/.ssh/dcss.key" +if [ ! -f "$MYKEY" ]; then + mkdir -p "${HOME}/.ssh" + curl -s "$SOURCEKEY" > "$MYKEY" + chmod 600 "$MYKEY" +fi +ssh -i "$MYKEY" dcss@crawl.tildeverse.org diff --git a/bin/envs_conntracks.sh b/bin/envs_conntracks.sh new file mode 100755 index 0000000..da05c10 --- /dev/null +++ b/bin/envs_conntracks.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +[[ "$EUID" -ne 0 ]] && printf 'Please run as root!\n' && exit 1 + +log_file='/var/log/envs_conntrack.log' + +c_local="$(tail -1 /var/log/conntrack.log | awk '{print $17}')" + +lxc_c=( $(for i in $(lxc-ls --active -1); do tail -1 /var/lib/lxc/"$i"/rootfs/var/log/conntrack.log | awk '{print $15}' ; done) ) +lxc_sum="$(echo $(printf %d+ ${lxc_c[@]})0 | bc)" + +c_sum="$((c_local + lxc_sum))" +echo "conntrack: $c_sum" >> "$log_file" + +exit 0 diff --git a/bin/envs_gemini_genpage.sh b/bin/envs_gemini_genpage.sh new file mode 100755 index 0000000..7130c21 --- /dev/null +++ b/bin/envs_gemini_genpage.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +# +# envs.net - generate index.gmi +# - this script is called by /etc/cron.d/envs_gemini +# + +[[ "$EUID" -ne 0 ]] && printf 'Please run as root!\n' && exit 1 + +### + +userlist() { + mapfile -t users < <(jq -Mr '.data.users|keys[]' /var/www/envs.net/users_info.json) + for USERNAME in "${users[@]}"; do + if [ -f /home/"$USERNAME"/public_gemini/index.gmi ]; then + [[ ! -L /var/gemini/\~"$USERNAME" ]] && ln -s /home/"$USERNAME"/public_gemini /var/gemini/\~"$USERNAME" + printf '=> gemini://envs.net/~%s/ ~%s\n' "$USERNAME" "$USERNAME" + else + [[ -L /var/gemini/\~"$USERNAME" ]] && unlink /var/gemini/\~"$USERNAME" + fi + done +} + +# +# INDEX.GMI +# +cat << EOM >> /tmp/index.gmi_tmp +welcome on envs.net - gemini +$(figlet -f smslant envs.net) + environments + + +envs.net is a minimalist, non-commercial +shared unix system and will always be free to use. + +we are linux lovers, sysadmins, programmer and users who like build +webpages, write blogs, chat online, play cool console games and so much +more. you wish to join with an small user space? + +join the team today! +=> https://envs.net/signup/ signup for a envs.net account (html) + +visit us in gopher and html lands for more info. +=> https://envs.net website (html) +=> gopher://envs.net gophermap (gopher) + + +here is a list of our esteemed users: +if you are not appearing on this list, create your index.gmi in ~/public_gemini + +$(userlist) + +EOM + + +mv /tmp/index.gmi_tmp /var/gemini/index.gmi + +# +exit 0 diff --git a/bin/envs_mysql.sh b/bin/envs_mysql.sh new file mode 100755 index 0000000..57646d7 --- /dev/null +++ b/bin/envs_mysql.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +CMD="$1" +DB="$2" +BACKUP_DIR="/home/$USER/backup" + +print_usage() { + printf 'envs.net | mysql backup & restore\n\n' + printf 'Usage: %s\n\t backup\t\t\t - backup your default user database (%s)\n' "$(basename "$0")" "$USER" + printf '\t backup \t - backup database\n' + printf '\t restore\t\t - restore your latest user database\n' + printf '\t restore \t - restore database\n' +} + +backup() { + [[ -z "$DB" ]] && DB="$USER" + test ! -d "$BACKUP_DIR" && mkdir -p "$BACKUP_DIR" && chmod 700 "$BACKUP_DIR" + + mysqldump -u "$USER" "$DB" -p | gzip -c > "$BACKUP_DIR"/db_"$(date +%F.%H%M%S)".sql.gz + find "$BACKUP_DIR"/db_*.gz -maxdepth 1 -type f -mtime +7 -delete +} + +restore() { + if [[ -z "$DB" ]]; then + latest=''; for f in "$BACKUP_DIR"/db_*.gz; do [[ "$f" -nt "$latest" ]] && latest="$f"; done + [[ -z "$latest" ]] && printf 'no restore file found in %s!\n' "$BACKUP_DIR" && exit 0 + DB="$latest" + gunzip < "$DB" | mysql -u "$USER" "$USER" -p + else + gunzip < "$BACKUP_DIR"/"$DB" | mysql -u "$USER" "$DB" -p + fi +} + +[[ $# -lt 1 ]] && print_usage && exit 1 + +case "$CMD" in + backup*) backup;; + + restore*) restore;; + + *) print_usage;; +esac + +# +exit 0 diff --git a/bin/envs_stats.sh b/bin/envs_stats.sh new file mode 100755 index 0000000..4a83234 --- /dev/null +++ b/bin/envs_stats.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +[[ "$EUID" -ne 0 ]] && printf 'Please run as root!\n' && exit 1 + +test ! -f /var/www/envs.net/stats/ && mkdir -p /var/www/envs.net/stats/ + +{ + zcat /var/log/nginx/other_vhosts_access.*.gz + cat /var/log/nginx/other_vhosts_access.log.1 + cat /var/log/nginx/other_vhosts_access.log +} | awk '$8=$1$8' | goaccess -a \ + -o /var/www/envs.net/stats/index.html \ + --ignore-panel=HOSTS \ + --ignore-panel=KEYPHRASES \ + --log-format=VCOMBINED - + +exit 0 diff --git a/bin/envs_sysinfo.sh b/bin/envs_sysinfo.sh new file mode 100755 index 0000000..9ec705e --- /dev/null +++ b/bin/envs_sysinfo.sh @@ -0,0 +1,330 @@ +#!/usr/bin/env bash +# +# envs.net - generate sysinfo.json and sysinfo.php +# - this script is called by /etc/cron.d/envs_sysinfo +# +WWW_PATH='/var/www/envs.net' +DOMAIN='envs.net' + +[[ "$EUID" -ne 0 ]] && printf 'Please run as root!\n' && exit 1 + +### + +# define packages by category for sysinfo.php Page +services=(0x0 bbj cryptpad getwtxt gitea gophernicus jetforce mariadb-server nginx openssh-server privatebin searx termbin tt-rss thelounge znc) +readarray -t sorted_services < <(printf '%s\n' "${services[@]}" | sort) + + +shells=(bash csh dash elvish fish ksh mksh sash tcsh xonsh yash zsh) +readarray -t sorted_shells < <(printf '%s\n' "${shells[@]}" | sort) + + +editors=(emacs micro nano neovim vim) +readarray -t sorted_editors < <(printf '%s\n' "${editors[@]}" | sort) + + +inet_clients=(alpine av98 bombadillo curl irssi lynx neomutt mutt mosh openssh-client pb toot weechat wget vf1) +readarray -t sorted_inet_clients < <(printf '%s\n' "${inet_clients[@]}" | sort) + + +coding_pkg=(cargo clang clisp clojure crystal default-jdk default-jre elixir erlang flex + g++ gcc gcl gdc gforth ghc go golang guile-2.2 inform lua5.1 lua5.2 lua5.3 mono-complete + nasm nodejs octave perl php picolisp ponyc python python2.7 python3 racket ruby rustc scala tcl yasm) +readarray -t sorted_coding_pkg < <(printf '%s\n' "${coding_pkg[@]}" | sort) + + +coding_tools=(ack bison build-essential clisp cl-launch cvs devscripts ecl gawk git gron initscripts jq latex-mk latexmk + make mawk mercurial rake ripgrep sbcl shellcheck subversion texlive-full virtualenv yarn) +readarray -t sorted_coding_tools < <(printf '%s\n' "${coding_tools[@]}" | sort) + + +misc=(aria2 bc busybox burrow byobu clinte gfu goaccess hugo jekyll mariadb-client mathomatic mathtex mkdocs + pandoc pelican screen sqlite3 tmux todotxt-cli twtxt zola) +readarray -t sorted_misc < <(printf '%s\n' "${misc[@]}" | sort) + +### + +custom_pkg_desc() { + local pkg="$1" + case "$pkg" in + # packages + av98) pkg_desc='AV-98 - Command line gemini client. High speed, low drag.';; + bombadillo) pkg_desc='Bombadillo is a modern Gopher & Gemini client for the terminal';; + burrow) pkg_desc='a helper for building and managing a gopher hole';; + clinte) pkg_desc='a community notices system';; + crystal) pkg_desc='Compiler for the Crystal language';; + gfu) pkg_desc='A utility for formatting gophermaps';; + go) pkg_desc='tool for managing Go source code';; + goaccess) pkg_desc='fast web log analyzer and interactive viewer';; + micro) pkg_desc='a new modern terminal-based text editor';; + pb) pkg_desc='a helper utility for using 0x0 pastebin services';; + twtxt) pkg_desc='Decentralised, minimalist microblogging service for hackers';; + vf1) pkg_desc='VF-1 - Command line gopher client. High speed, low drag.';; + zola) pkg_desc='single-binary static site generator written in rust';; + esac +} + + +# +# SYSINFO.JSON +# +JSON_FILE="$WWW_PATH/sysinfo.json" +TMP_JSON='/tmp/sysinfo.json_tmp' + +print_pkg_version() { + local pkg_version + for pkg in $(dpkg-query -f '${binary:Package}\n' -W); do + pkg_version="$(dpkg-query -f '${Version}\n' -W "$pkg")" + + printf '\t\t\t"%s": "%s",\n' "$pkg" "$pkg_version" + done +} + + +cat< "$TMP_JSON" +{ + "timestamp": "$(date +'%s')", + "data": { + "info": { + "name": "envs", + "description": "envs.net is a minimalist, non-commercial shared unix system and will always be free to use.", + "located": "germany", + "maintainer": "Sven Kinne (~creme) - creme@envs.net", + "website": "https://$DOMAIN", + "signup_url": "https://$DOMAIN/signup/", + "gopher": "gopher://envs.net/", + "email": "hostmaster@$DOMAIN", + "admin_email": "sudoers@$DOMAIN", + "user_count": $(find /home -mindepth 1 -maxdepth 1 | wc -l) + }, + "system": { + "os": "$(lsb_release -sd)", + "uptime": "$(cat /proc/uptime)", + "uname": "$(uname -a)", + "board": "$(hostnamectl status | awk '/Chassis/ {print $2}')", + "cpuinfo": "$(awk '/system type|model name/{gsub(/^.*:[ ]*/,"");print $0;exit}' /proc/cpuinfo)", + "cpucount": "$(grep -c ^processor /proc/cpuinfo)" + }, + "services": { + "0x0": { + "desc": "the null pointer - file hosting and url shortener", + "version": "-", + "url": "https://envs.sh/" + }, + "bbj": { + "desc": "Bulletin Butter & Jelly: An HTTP bulletin board server for small communities", + "version": "-", + "url": "https://bbj.envs.net/" + }, + "cryptpad": { + "desc": "collaborative real time editing", + "version": "$(curl -s https://pad."$DOMAIN"/api/config | awk '/ver=/ {print $2}' | sed -e 's/"ver=//' -e '$ s/"$//')", + "url": "https://pad.envs.net/" + }, + "getwtxt": { + "desc": "a twtxt registry service", + "version": "$(curl -s https://twtxt."$DOMAIN"/api/plain/version | sed 's/getwtxt v//')", + "url": "https://twtxt.envs.net/" + }, + "gitea": { + "desc": "a painless self-hosted git service written in go", + "version": "$(lxc-attach -n gitea -- bash -c "gitea --version | awk '{print \$3}'")", + "url": "https://git.envs.net/" + }, + "gophernicus": { + "desc": "a modern full-featured (and hopefully) secure gopher daemon", + "version": "$(/usr/sbin/gophernicus -v | sed 's/Gophernicus\///' | awk '{print $1}')", + "url": "gopher://envs.net/" + }, + "jetforce": { + "desc": "an tcp server for the gemini protocol", + "version": "$(/usr/local/bin/jetforce -V | awk '{printf $2}')", + "url": "gemini://envs.net/" + }, + "privatebin": { + "desc": "a pastebin service", + "version": "$(lxc-attach -n pb -- bash -c "awk '/Current version:/ {print \$3}' /var/www/PrivateBin/README.md | sed '$ s/*$//'")", + "url": "https://pb.envs.net/" + }, + "searx": { + "desc": "privacy-respecting metasearch engine", + "version": "$(curl -s https://searx."$DOMAIN"/config | jq -Mr .version)", + "url": "https://searx.envs.net/" + }, + "termbin": { + "desc": "a command line pastebin", + "version": "-", + "url": "https://tb.envs.net/" + }, + "thelounge": { + "desc": "a self-hosted web irc client", + "version": "$(sudo -u thelounge /srv/thelounge/.yarn/bin/thelounge -v | sed 's/v//')", + "url": "https://webirc.envs.net/" + }, + "tt-rss": { + "desc": "tiny tiny rss - web-based news feed (rss/atom) aggregator", + "version": "$(lxc-attach -n rss -- bash -c "dpkg -s tt-rss | awk '/Version:/ {print \$2}' | head -n1")", + "url": "https://rss.envs.net/" + }, + "znc": { + "desc": "advanced modular irc bouncer", + "version": "$(dpkg -s znc | awk '/Version:/ {print $2}' | head -n1)", + "url": "https://znc.envs.net/" + } + }, + "packages": { + "av98": "$(/usr/local/bin/av98 --version | awk '{print $2}')", + "bombadillo": "$(/usr/local/bin/bombadillo -v | sed 's/Bombadillo v//')", + "burrow": "$(/usr/local/bin/burrow -v | sed 's/v//')", + "clinte": "$(/usr/local/bin/clinte -V | awk '{print $2}')", + "gfu": "$(/usr/local/bin/gfu -v | sed '/version/s/.*version \([^ ][^ ]*\)[ ]*.*/\1/')", + "go": "$(sed 's/go//' /usr/local/go/VERSION)", + "goaccess": "$(/usr/bin/goaccess -V | head -1 | sed -e 's/GoAccess - //' -e '$ s/.$//')", + "micro": "$(/usr/local/bin/micro -version | head -n1 | awk '{print $2}')", + "pb": "$(/usr/local/bin/pb -v)", + "twtxt": "$(/usr/local/bin/twtxt --version | awk '{printf $3}')", + "vf1": "$(/usr/local/bin/vf1 --version | awk '{print $2}')", + "zola": "$(/usr/local/bin/zola -V | awk '{print $2}')", +$(print_pkg_version) +EOM + # remove trailing ',' on last line + sed -i '$ s/,$//' "$TMP_JSON" + +cat<> "$TMP_JSON" + } + } +} +EOM + +mv "$TMP_JSON" "$JSON_FILE" +chown root:www-data "$JSON_FILE" + + +# +# SYSINFO.PHP +# +print_pkg_info() { + local pkg="$1" + + local pkg_version + pkg_version="$(jq -Mr '.data.packages."'"$pkg"'"|select (.!=null)' "$JSON_FILE")" + [[ "$pkg_version" = '' ]] && pkg_version='n.a.' + + local pkg_desc + custom_pkg_desc "$pkg" + [[ "$pkg_desc" = '' ]] && pkg_desc="$(apt-cache show "$pkg" | awk '/Description-en/ {print substr($0, index($0,$3))}' | head -1)" + [[ "$pkg_desc" = '' ]] && pkg_desc="$(apt-cache search ^"$pkg"$ | awk '{print substr($0, index($0,$3))}')" + [[ "$pkg_desc" = '' ]] && pkg_desc='n.a.' + # remove description-en string + pkg_desc="${pkg_desc//Description-en: /}" + # replace double qoutes with single qoute + pkg_desc="${pkg_desc//\"/\'}" + # string to lowercase + pkg_desc="${pkg_desc,,}" + + printf '\t %s %s %s \n' "$pkg" "$pkg_version" "$pkg_desc" +} + +print_pkg_info_services() { + local pkg="$1" + + local pkg_desc + pkg_desc="$(jq -Mr '.data.services."'"$pkg"'".desc|select (.!=null)' "$JSON_FILE")" + + local pkg_version + pkg_version="$(jq -Mr '.data.services."'"$pkg"'".version|select (.!=null)' "$JSON_FILE")" + + local s_url + s_url="$(jq -Mr '.data.services."'"$pkg"'".url|select (.!=null)' "$JSON_FILE")" + + printf '\t %s %s %s \n' "$s_url" "$pkg" "$pkg_version" "$pkg_desc" +} + +print_category() { + local category="$1" + shift + local arr=("$@") + + if [ "$category" = 'services' ]; then + printf '
# %s\n' "$category" "${category//_/ }" + else + printf '
# %s\n' "$category" "${category//_/ }" + fi + + printf '\n' + printf '\n' + + if [ "$category" = 'services' ]; then + for pkg in "${arr[@]}"; do + # check service is in json + s_in_j="$(jq -Mr '.data.services."'"$pkg"'"|select (.!=null)' "$JSON_FILE")" + + if [ -n "$s_in_j" ]; then + print_pkg_info_services "$pkg" + else + print_pkg_info "$pkg" + fi + done + else + for pkg in "${arr[@]}"; do print_pkg_info "$pkg"; done + fi + + printf '
Package Version Description
\n' +} + + +cat< /tmp/sysinfo.php_tmp + + + +
+ +
+
< back
+
+ +
+
+
+

sysinfo

+ +full data source: https://$DOMAIN/sysinfo.json +webserver stats: https://$DOMAIN/stats/ + +server admin: ~creme +
+
+ +
+this is a static list of the package informations. it updates once per day.
+
+# can i get [package] installed?
+probably! send an email with your suggestion to sudoers@$DOMAIN.
+
+$(print_category 'services' "${sorted_services[@]}")
+$(print_category 'shells' "${sorted_shells[@]}")
+$(print_category 'editors' "${sorted_editors[@]}")
+$(print_category 'online_browser_and_clients' "${sorted_inet_clients[@]}")
+$(print_category 'coding_packages' "${sorted_coding_pkg[@]}")
+$(print_category 'coding_tools' "${sorted_coding_tools[@]}")
+$(print_category 'misc' "${sorted_misc[@]}")
+
+
+ + + +EOM + +mv /tmp/sysinfo.php_tmp "$WWW_PATH"/sysinfo.php +chown root:www-data "$WWW_PATH"/sysinfo.php + + +# +exit 0 diff --git a/bin/envs_toot b/bin/envs_toot new file mode 100755 index 0000000..4f9b222 --- /dev/null +++ b/bin/envs_toot @@ -0,0 +1,11 @@ +#!/usr/bin/env sh + +printf 'toot as envs.net\n\n' + +if [ -n "$1" ] && [ -z "$2" ]; then + sudo -u services /usr/bin/toot post "$1" +else + printf 'usage: envs_toot "your message"\n' +fi + +exit 0 diff --git a/bin/envs_user_manage b/bin/envs_user_manage new file mode 100755 index 0000000..c97993c --- /dev/null +++ b/bin/envs_user_manage @@ -0,0 +1,175 @@ +#!/usr/bin/env bash + +domain='envs.net' +short_dom="$(echo $domain | awk -F. '{printf $1}')" + + +cmd="$1" +user="$2" +mailTo="$3" +ssh_pubkey="$4" + +newpw=$(pwgen -s 12 1) +pwcrypt=$(perl -e "print crypt('${newpw}', 'sa');") + +# mail header +head_mime='MIME-Version: 1.0' +head_type='Content-type: text/plain; charset=utf-8' +head_def="$head_mime\r\n$head_type" + +### + +add_user_db() { + mysql -u root << EOF +CREATE DATABASE $user; +GRANT ALL PRIVILEGES ON $USER.* TO '$user'@'localhost' IDENTIFIED BY '$newpw'; +FLUSH PRIVILEGES; +EOF +} + +del_user_db() { + mysqldump -u root "$user" > /tmp/"$user".sql + mv /tmp/"$user".sql /root/mysql_dumps/"$user".sql + + mysql -u root << EOF +DROP DATABASE $user; +FLUSH PRIVILEGES; +EOF +} + + +add_user() { + useradd -m -g 9999 -s /bin/bash -p "$pwcrypt" "$user" + + # set user quota + echo "$user hard nproc 200" | tee /etc/security/limits.d/"$user" >/dev/null 2>&1 + setquota -u "$user" 1024M 1536M 0 0 / + + # set mail aliases + echo "$user: $user@$domain" | tee -a /etc/aliases >/dev/null 2>&1 + echo "$user: $user@$domain" | tee -a /etc/email-addresses >/dev/null 2>&1 + + # systemd service + chown -R "$user":"$short_dom" /home/"$user"/.config/systemd/user/ + + # set users ssh pub key + if [ -n "$ssh_pubkey" ]; then + echo "$ssh_pubkey" | tee /home/"$user"/.ssh/authorized_keys + else + nano /home/"$user"/.ssh/authorized_keys + fi + chmod 700 /home/"$user"/.ssh/ + chmod 644 /home/"$user"/.ssh/authorized_keys + chown -R "$user":"$short_dom" /home/"$user"/.ssh + + # setup database + add_user_db + + # setup email mailbox + lxc-attach -n mail -- bash -c "/usr/local/bin/coreapi action accounts create \ + -p username=$user@$domain -p role=SimpleUsers -p language=en \ + -p password=$newpw -p secondary_email=$mailTo >/dev/null 2>&1 " + + sleep 3 + + # send readme mail + readme_sub="Subject: Welcome ~$user | please readme!" + readme_mail="$head_def\r\nTo: $user@$domain\r\nFrom: sudoers@$domain\r\n$readme_sub" + + echo -e "$readme_mail\r\n$(cat /usr/local/bin/welcome-readme.tmpl)" | sendmail "$user"@"$domain" + + # send welcome mail + wel_sub="Subject: Welcome to $domain | ~$user" + wel_mail="$head_def\r\nTo: $mailTo\r\nCC: $user@$domain\r\nFrom: hosting@$domain\r\n$wel_sub" + + sleep 1 && echo -e "$wel_mail\r\n$(sed -e s/_username_/"$user"/g -e s/_password_/"$newpw"/ /usr/local/bin/welcome-email.tmpl)" \ + | sendmail "$user"@"$domain" "$mailTo" + + # subscribing to mailing list + sleep 1 && echo -e "$head_def\r\nTo: team-join@$domain\r\nFrom: $user@$domain\r\nSubject: subscribe\r\n" \ + | sudo -u "$user" sendmail team-join@"$domain" + + # setup mutt + echo -e "$(sed -e s/_username_/"$user"/g -e s/_password_/"$newpw"/ /home/"$user"/.muttrc)" > /home/"$user"/.muttrc + chmod go-r /home/"$user"/.muttrc + printf '\n~%s\n' "$user" > /home/"$user"/.mutt/signature + + # setup znc account + sudo -u znc pkill -SIGUSR1 znc && pkill znc + sudo -u znc /srv/znc/add_znc_user.sh "$user" + systemctl start znc + + # setup weechat + sed -i s/_username_/"$user"/g /home/"$user"/.weechat/irc.conf + + # cleanup /etc/skel/ git stuff from user home + rm -rf /home/"$user"/.git /home/"$user"/README.md + + # envs user update (userlist, recently updates and users_info.json) + /usr/local/bin/envs_user_updated.sh + + # announcing new user on mastodon + sudo -u services toot post "welcome new user ~$user" +} + + +del_user() { + # unsubscribe mailing list + # ?? + echo -e "$head_def\r\nTo: team-leave@$domain\r\nFrom: $user@$domain\r\nSubject: leave\r\n" | sudo -u "$user" sendmail team-leave@"$domain" + # remove user + deluser --remove-home "$user" + # unset user quota + rm /etc/security/limits.d/"$user" + # unset mail aliases + sed -i /"$user"/d /etc/aliases + sed -i /"$user"/d /etc/email-addresses + # remove email mailbox + # get userid from lxc-attach + mail_userid=$(lxc-attach -n mail -- bash -c "/usr/local/bin/coreapi action accounts list -p search=$user@$domain | jq '.[] | .pk'") + lxc-attach -n mail -- bash -c "/usr/local/bin/coreapi action accounts delete -p id=$mail_userid" + # remove database + del_user_db + # unlink gemini + [[ -L /var/gemini/\~"$user" ]] && unlink /var/gemini/\~"$user" + # remove znc account + printf '\n!!! ADMIN: please remove %s also from lists.%s and znc.%s !!!\n\n' "$user" "$domain" "$domain" +} + + +[[ "$EUID" -ne 0 ]] && printf 'Please run as root!\n' && exit 1 + +case "$cmd" in + add) [[ $# -lt 3 ]] && printf 'not enough args\n' && exit 1 + if ! id -u "$user" >/dev/null 2>&1; then + printf '\nAdd User %s to %s\n' "$user" "$domain" + printf 'mail to: %s\n\n' "$mailTo" + add_user + else + printf 'User already exists!\n' + fi + ;; + + del) [[ $# -lt 2 ]] && printf 'not enough args\n' && exit 1 + if id -u "$user" >/dev/null 2>&1; then + printf '\nDelete User %s from %s?\n' "$user" "$domain" + select yn in "Yes" "No"; do + case $yn in + Yes ) del_user ; break ;; + No ) break ;; + esac ; done + else + printf 'User not exists!\n' + fi + ;; + + *) printf '%s | User Account Setup\n\n' "$domain" + printf 'Usage: %s\n Add a User:\n' "$(basename "$0")" + printf '\t%s add "username" "email" "ssh-pubkey"\n' "$(basename "$0")" + printf ' Delete a User:\n' + printf '\t%s del "username"\n' "$(basename "$0")" + ;; +esac + +# +exit 0 diff --git a/bin/envs_user_updated.sh b/bin/envs_user_updated.sh new file mode 100755 index 0000000..06aa5e9 --- /dev/null +++ b/bin/envs_user_updated.sh @@ -0,0 +1,233 @@ +#!/usr/bin/env bash +# +# envs.net - generate user_updates.php and users_info.json +# - this script is called by /etc/cron.d/envs_sysinfo +# +WWW_PATH='/var/www/envs.net' +DOMAIN="envs.net" + + +[[ "$EUID" -ne 0 ]] && printf 'Please run as root!\n' && exit 1 + +# +# user_updates.php +# + +LIST="$(stat --format=%Z\ %n /home/*/public_html/* | grep -v updated | grep -v your_index_template.php | grep -v cgi-bin | sort -r)" +echo "$LIST" | perl /usr/local/bin/envs_user_updated_genpage.pl > /tmp/user_updates.php_tmp + +mv /tmp/user_updates.php_tmp "$WWW_PATH"/user_updates.php +chown root:www-data "$WWW_PATH"/user_updates.php + + +# +# users_info.json +# +TMP_JSON='/tmp/users_info.json_tmp' + +cat << EOM > "$TMP_JSON" +{ + "timestamp": "$(date +'%s')", + "data": { + "info": { + "name": "envs", + "description": "envs.net is a minimalist, non-commercial shared unix system and will always be free to use.", + "located": "germany", + "maintainer": "Sven Kinne (~creme) - creme@envs.net", + "website": "https://$DOMAIN", + "signup_url": "https://$DOMAIN/signup/", + "gopher": "gopher://envs.net/", + "email": "hostmaster@$DOMAIN", + "admin_email": "sudoers@$DOMAIN", + "user_count": $(find /home -mindepth 1 -maxdepth 1 | wc -l) + }, + "users": { +EOM +# user header + for USERNAME in /home/* + do + USER_HOME="$USERNAME" + USERNAME="${USERNAME/\/home\//}" + INFO_FILE="$USER_HOME/.envs" + + cat << EOM >> "$TMP_JSON" + "$USERNAME": { + "home": "$USER_HOME", + "email": "$USERNAME@$DOMAIN", +EOM +# desc + if [[ -f "$INFO_FILE" ]]; then + desc="$(sed -n '/^desc=/{s#^.*=##;p}' "$INFO_FILE")" + + if [[ -z "$desc" ]] || [[ "$desc" == 'a short describtion or message' ]]; then + cat << EOM >> "$TMP_JSON" + "desc": "", +EOM + else + cat << EOM >> "$TMP_JSON" + "desc": "$desc", +EOM + fi + else + cat << EOM >> "$TMP_JSON" + "desc": "", +EOM + fi +# website + if [[ -f "$USER_HOME"/public_html/index.php ]] || [[ "$(test -f "$USER_HOME"/public_html/index.*htm*; echo $?)" -eq 0 ]]; then + cat << EOM >> "$TMP_JSON" + "website": "https://$DOMAIN/~$USERNAME/", +EOM + else + cat << EOM >> "$TMP_JSON" + "website": "", +EOM + fi +# gopher + if [ -f "$USER_HOME"/public_gopher/gophermap ]; then + cat << EOM >> "$TMP_JSON" + "gopher": "gopher://$DOMAIN/1/~$USERNAME/", + "gopherproxy": "https://gopher.$DOMAIN/$DOMAIN/1/~$USERNAME/", +EOM + else + cat << EOM >> "$TMP_JSON" + "gopher": "", + "gopherproxy": "", +EOM + fi +# gemini + if [ -f "$USER_HOME"/public_gemini/index.gmi ]; then + cat << EOM >> "$TMP_JSON" + "gemini": "gemini://$DOMAIN/~$USERNAME/", +EOM + fi +# blog + if [[ "$(find "$USER_HOME"/public_html/blog/ -maxdepth 1 2>/dev/null | wc -l)" -ge 3 ]]; then + cat << EOM >> "$TMP_JSON" + "blog": "https://$DOMAIN/~$USERNAME/blog/", +EOM + else + cat << EOM >> "$TMP_JSON" + "blog": "", +EOM + fi +# twtwt + if [[ -f "$USER_HOME"/public_html/twtxt.txt ]]; then + cat << EOM >> "$TMP_JSON" + "twtxt": "https://$DOMAIN/~$USERNAME/twtxt.txt", +EOM + else + cat << EOM >> "$TMP_JSON" + "twtxt": "", +EOM + fi +# user custom infos from .envs file (max. 10 entrys) + if [[ -f "$INFO_FILE" ]]; then + count_entry='0' # use to limit entrys + count_field_entry='0' # use to separat array line by line + + unset field_exists; declare -a field_exists=() # contains field names to limit entrys + unset field_is_array; declare -a field_is_array=() # contains array fields to printf correct json entrys + unset line_to_set; declare -A line_to_set # contains user info lines + + # check 'INFO_FILE' and add entrys to 'line_to_set' array + while read -r LINE ; do + if [[ -n "$LINE" ]] && ! [[ "$LINE" = '#'* ]] && ! [[ "$LINE" = 'desc='* ]]; then + user_field="${LINE//=*/}" + user_value="${LINE//*=/}" + + if ! [[ ":${field_exists[*]}:" =~ $user_field ]]; then + # entry will be a single line + count_entry="$(( "$count_entry" + 1 ))"; [[ "$count_entry" -le '10' ]] || continue + field_exists+=( "$user_field" ) + line_to_set["$user_field","$count_field_entry"]+="$user_value" + else + # entry will be a array + if ! [[ ":${field_is_array[*]}:" =~ $user_field ]]; then + field_is_array+=( "$user_field" ) + fi + count_field_entry="$(( "$count_field_entry" +1 ))" + line_to_set["$user_field","$count_field_entry"]+="$user_value" + fi + fi + done <<< "$(tac "$INFO_FILE")" # read file from buttom + + # add users custom entrys from line_to_set (single lines before arrays) + # + # single line entrys + for field in "${!line_to_set[@]}"; do + field_name="${field//,*/}" + + if ! [[ ":${field_is_array[*]}:" =~ $field_name ]]; then + cat << EOM >> "$TMP_JSON" + "$field_name": "${line_to_set[$field]}", +EOM + fi + done + # + # array line entrys + field_in_progress='' + + for field in "${!line_to_set[@]}"; do + field_name="${field//,*/}" + field_count="${field//*,/}" + + if [[ ":${field_is_array[*]}:" =~ $field_name ]]; then + # begin of user def. array + if ! [[ "$field_in_progress" = "$field_name" ]]; then + field_in_progress="$field_name" + + cat << EOM >> "$TMP_JSON" + "$field_name": [ + "${line_to_set[$field]}", +EOM + else + # continue user def. array + if ! [[ "$field_count" -eq '0' ]]; then + cat << EOM >> "$TMP_JSON" + "${line_to_set[$field]}", +EOM + # end of user def. array + else + unset field_in_progress + cat << EOM >> "$TMP_JSON" + "${line_to_set[$field]}" + ], +EOM + fi + fi + fi + done + fi +# ssh + cat << EOM >> "$TMP_JSON" + "ssh-pubkey": [ +EOM + while read -r LINE ; do + [[ "$LINE" == 'ssh'* ]] && printf '\t\r\t\r\t\r\t\r\t"%s",\n' "$LINE" >> "$TMP_JSON" + done < "$USER_HOME"/.ssh/authorized_keys + # remove trailing ',' for the last pubkey + sed -i '$ s/,$//' "$TMP_JSON" + + # close user ssh pubkey array ']' and user part. '},' + cat << EOM >> "$TMP_JSON" + ] + }, +EOM +# EOF + done + # remove trailing ',' on last user entry + sed -i '$ s/,$//' "$TMP_JSON" + + cat << EOM >> "$TMP_JSON" + } + } +} +EOM + + +mv "$TMP_JSON" "$WWW_PATH"/users_info.json +chown root:www-data "$WWW_PATH"/users_info.json + +# +exit 0 diff --git a/bin/envs_user_updated_genpage.pl b/bin/envs_user_updated_genpage.pl new file mode 100755 index 0000000..17731b1 --- /dev/null +++ b/bin/envs_user_updated_genpage.pl @@ -0,0 +1,50 @@ +#!/usr/bin/perl +# +# source from pgadey (ctrl-c.club) +# url: https://github.com/pgadey/bin/blob/master/ctrl-c.club +# + +print " + + +
+ +
+
< back
+
+ +
+
+
+

recently user updates

+
+
+ +
+this is a static list of the pages modified in /home/*/public_html/*. it updates every hour.
+
    \n"; + +while (<>) { + chomp; + ($date, $index) = split(/ /, $_); + $date = `date --date="\@$date" +'%F %H:%M:%S'`; + $author = $index; + $file = $index; + $author =~ s%/home/(\w+)/public_html/(\S+)%$1%; + $file =~ s%/home/(\w+)/public_html/(\S+)%$2%; + print "
  • \~$author ($file) at $date
  • \n"; +}; + +print "
+
+
+ +"; diff --git a/bin/hole b/bin/hole new file mode 100755 index 0000000..0d71d0f --- /dev/null +++ b/bin/hole @@ -0,0 +1,3 @@ +#!/bin/sh + +lynx gopher://localhost "$@" diff --git a/bin/idiff b/bin/idiff new file mode 100755 index 0000000..69203d7 --- /dev/null +++ b/bin/idiff @@ -0,0 +1,74 @@ +#!/bin/sh + +# Color diff output, for human consumption + +# License: LGPLv2 +# Author: +# http://www.pixelbeat.org/ +# Notes: +# If 2 parameters are passed, then they are passed to +# the `diff -Naru` command first. Otherwise the parameters +# (or stdin) are assumed to be diff format and are colourised. +# +# VIM can be useful for viewing diffs also: +# diff -Naru a b | vim -R - +# vim -R a-b.diff +# Changes: +# V0.1, 12 Feb 2008, Initial release +# V0.2, 18 Feb 2008, Use tput rather than hardcoding escape sequences. +# V0.3, 24 Apr 2008, Support Mac OS X +# V0.4, 30 Apr 2008, P@draigBrady.com +# Use $PAGER if set +# Manfred Schwarb +# Support `diff -c` format fully. +# Pointed out issues with less -EF options. +# Suggested to use the less -S option. +# V0.5, 18 Jun 2009, P@draigBrady.com +# Delineate each file level item with highlight. +# Simplify expressions by using '&' in replacement. +# Use 't' after all matches for consistency and speed. + +# less -K reportedly not available on older Mac OS X +less -K -Ff /dev/null 2>/dev/null && CTRL_C_EXITS="-K" + +RED=1; GREEN=2; BLUE=4; BRIGHT='1;' + +tputc() { + bright=$1; colour=$2 + [ "$bright" ] && tput bold + tput setaf $colour +} + +DEL="`tputc $BRIGHT $RED`" +ADD="`tputc $BRIGHT $GREEN`" +CHG="`tputc $BRIGHT $BLUE`" +FIL="`tput smso`" #highlight file level items +RST="`tput sgr0`" + +if [ "$#" -eq "2" ]; then + diff -Naru "$@" +else + cat "$@" +fi | +sed " +s/^\*\{3\}.*\*\{4\}/$CHG&$RST/;t + s/^-\{3\}.*-\{4\}/$CHG&$RST/;t + s/^@.*/$CHG&$RST/;t + s/^[0-9].*/$CHG&$RST/;t + s/^!.*/$CHG&$RST/;t + + s/^-.*/$DEL&$RST/;t + s/^<.*/$DEL&$RST/;t + + s/^\*.*/$ADD&$RST/;t + s/^\+.*/$ADD&$RST/;t + s/^>.*/$ADD&$RST/;t + + s/^Only in.*/$FIL&$RST/;t + s/^Index: .*/$FIL&$RST/;t + s/^diff .*/$FIL&$RST/;t +" | +${PAGER:-less -QRS $CTRL_C_EXITS} + +# could use less -EFX also, but for large files or lots of scrolling, this +# is a lot more obtrusive on the terminal as the [de]init codes not used. diff --git a/bin/motd b/bin/motd new file mode 100755 index 0000000..a735cca --- /dev/null +++ b/bin/motd @@ -0,0 +1,3 @@ +#!/bin/sh + +cat /var/run/motd.dynamic diff --git a/bin/online-users b/bin/online-users new file mode 100755 index 0000000..6cb75b3 --- /dev/null +++ b/bin/online-users @@ -0,0 +1,3 @@ +#!/bin/sh + +users | tr ' ' \\n | uniq | wc -l diff --git a/bin/webirc b/bin/webirc new file mode 100755 index 0000000..bf4b7ea --- /dev/null +++ b/bin/webirc @@ -0,0 +1,7 @@ +#!/bin/bash + +printf 'setting up your thelounge account\n\n' + +THELOUNGE_HOME=/srv/thelounge sudo -u thelounge /srv/thelounge/.yarn/bin/thelounge add "$USER" + +printf '\nyou can now log in to https://irc.envs.net as %s with the password you just created.\n' "$USER" diff --git a/bin/welcome-email.tmpl b/bin/welcome-email.tmpl new file mode 100644 index 0000000..0d0196e --- /dev/null +++ b/bin/welcome-email.tmpl @@ -0,0 +1,38 @@ +hello ~_username_, + +welcome to envs.net! + +your account has been established and you can ssh or mosh +into envs.net with the ssh key you supplied on registration. + +your password is "_password_". +please change it when you log in for the first time with ssh. +also you need to change the password on https://mail.envs.net ! +the password is used for imap/smtp auth(mail) and mysql. NOT shell login, +which is set to only use ssh key authentication. +your mail password will also used for znc.envs.net (imap-auth). + +the best way you can help envs.net is by working +to support a great system culture. build cool programs and +share them with others; and help others; be a +good example for others and have fun! + +your ~/public_www directory is served at: +https://envs.net/~_username_ , https://envs.net/u/_username_ +https://_username_.envs.net and https://_username_.envs.sh/. + +your mysql database is also has been provisioned. information below should +be used to connect to it: + +database name: _username_ +database user: _username_ +password: (see your password above) + +of course you can also use sqlite databases. + + +check out our help page at https://envs.net/help for more informations. + +we seeing you! :) + +envs.net ~creme diff --git a/bin/welcome-readme.tmpl b/bin/welcome-readme.tmpl new file mode 100644 index 0000000..9e332fc --- /dev/null +++ b/bin/welcome-readme.tmpl @@ -0,0 +1,33 @@ +hello, + +welcome to envs.net! + +you made it! we've set you up with a 'byobu' session with the +following default tabs: + + - weechat for irc + - mutt for email + - a shell + +if you're reading this, you're in the mutt pane. have a look +at the status bar at the bottom. the current windows are shown +in the bottom left, with several system status symbols on the right. + +some of the most important keybinds are: + + - f2: open a new window/tab + - f3/f4: prev/next windows + - f6: disconnect from you byobu session + - shift-f12 disable/enable byobu f-key bindings + +press shift-f1 to see a more complete list of keybinds, +but these will get you wherever you need to go. + +if you need help, switch to the first window and ask in irc. + +also, if you know what you're doing and would rather use a different +terminal multiplexer, run byobu-disable to prevent it from launching on login. + +we look forward to seeing you around! welcome to the envs.net! + +envs ~ admins diff --git a/etc/cron.d/backup b/etc/cron.d/backup new file mode 100644 index 0000000..39c69af --- /dev/null +++ b/etc/cron.d/backup @@ -0,0 +1,7 @@ +# +# BACKUP Server every day +# +SHELL=/bin/sh +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root + +13 1,13 * * * root /root/backup-server.sh >/dev/null 2>&1 diff --git a/etc/cron.d/botany b/etc/cron.d/botany new file mode 100644 index 0000000..56cbe5d --- /dev/null +++ b/etc/cron.d/botany @@ -0,0 +1,4 @@ +SHELL=/bin/sh +PATH=/usr/bin:/opt/services + +0 0 * * 0 services python /opt/services/botany/clear_weekly_users.py >/dev/null 2>&1 diff --git a/etc/cron.d/certbot b/etc/cron.d/certbot new file mode 100644 index 0000000..1667397 --- /dev/null +++ b/etc/cron.d/certbot @@ -0,0 +1,17 @@ +# /etc/cron.d/certbot: crontab entries for the certbot package +# +# Upstream recommends attempting renewal twice a day +# +# Eventually, this will be an opportunity to validate certificates +# haven't been revoked, etc. Renewal will only occur if expiration +# is within 30 days. +# +# Important Note! This cronjob will NOT be executed if you are +# running systemd as your init system. If you are running systemd, +# the cronjob.timer function takes precedence over this cronjob. For +# more details, see the systemd.timer manpage, or use systemctl show +# certbot.timer. +SHELL=/bin/sh +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin + +0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew --deploy-hook /etc/letsencrypt/renewal-hooks/deploy/envs.sh --renew-hook "systemctl reload nginx" diff --git a/etc/cron.d/conntrack b/etc/cron.d/conntrack new file mode 100644 index 0000000..c7c6515 --- /dev/null +++ b/etc/cron.d/conntrack @@ -0,0 +1,4 @@ +SHELL=/bin/sh +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin + +0-59/1 * * * * root /usr/local/bin/conntrack.sh && /usr/local/bin/envs_conntracks.sh >/dev/null 2>&1 diff --git a/etc/cron.d/envs_gemini b/etc/cron.d/envs_gemini new file mode 100644 index 0000000..7103ccf --- /dev/null +++ b/etc/cron.d/envs_gemini @@ -0,0 +1,7 @@ +# +# generate envs gemini - index.gem (once per hour) +# +SHELL=/bin/sh +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin + +0 * * * * root /usr/local/bin/envs_gemini_genpage.sh >/dev/null 2>&1 diff --git a/etc/cron.d/envs_stats b/etc/cron.d/envs_stats new file mode 100644 index 0000000..c2a0b4c --- /dev/null +++ b/etc/cron.d/envs_stats @@ -0,0 +1,7 @@ +# +# generate envs stats.html (once per hour) +# +SHELL=/bin/sh +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin + +0 * * * * root /usr/local/bin/envs_stats.sh >/dev/null 2>&1 diff --git a/etc/cron.d/envs_sysinfo b/etc/cron.d/envs_sysinfo new file mode 100644 index 0000000..1d52ada --- /dev/null +++ b/etc/cron.d/envs_sysinfo @@ -0,0 +1,7 @@ +# +# generate sysinfo.json and sysinfo.php every day +# +SHELL=/bin/sh +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin + +0 0 * * * root /usr/local/bin/envs_sysinfo.sh >/dev/null 2>&1 diff --git a/etc/cron.d/envs_user_updated_genpage b/etc/cron.d/envs_user_updated_genpage new file mode 100644 index 0000000..6b24700 --- /dev/null +++ b/etc/cron.d/envs_user_updated_genpage @@ -0,0 +1,8 @@ +# +# generate user_updates.php , users_info.json +# (once per hour) +# +SHELL=/bin/sh +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin + +0 * * * * root /usr/local/bin/envs_user_updated.sh >/dev/null 2>&1 diff --git a/etc/cron.d/update-blacklist b/etc/cron.d/update-blacklist new file mode 100644 index 0000000..a67a9c5 --- /dev/null +++ b/etc/cron.d/update-blacklist @@ -0,0 +1,4 @@ +SHELL=/bin/sh +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin + +33 23 * * * root /usr/local/sbin/update-blacklist.sh /etc/ipset-blacklist/ipset-blacklist.conf >/dev/null 2>/dev/null& diff --git a/etc/cron.d/update-blacklist_fail2ban b/etc/cron.d/update-blacklist_fail2ban new file mode 100644 index 0000000..9202e9f --- /dev/null +++ b/etc/cron.d/update-blacklist_fail2ban @@ -0,0 +1,6 @@ +SHELL=/bin/sh +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +0-59/30 * * * * root /usr/local/sbin/ipset-fail2ban.sh /etc/ipset-fail2ban/ipset-fail2ban.conf >/dev/null 2>/dev/null& +# clear list once per week +0 0 * * 0 root /usr/local/sbin/ipset-fail2ban.sh /etc/ipset-fail2ban/ipset-fail2ban.conf -c >/dev/null 2>&1 diff --git a/etc/etc/inetd.conf b/etc/etc/inetd.conf new file mode 100644 index 0000000..f76ea6c --- /dev/null +++ b/etc/etc/inetd.conf @@ -0,0 +1,43 @@ +# /etc/inetd.conf: see inetd(8) for further informations. +# +# Internet superserver configuration database +# +# +# Lines starting with "#:LABEL:" or "##" should not +# be changed unless you know what you are doing! +# +# If you want to disable an entry so it isn't touched during +# package updates just comment it out with a single '#' character. +# +# Packages should modify this file by using update-inetd(8) +# +# +# +#:INTERNAL: Internal services +#discard stream tcp nowait root internal +#discard dgram udp wait root internal +#daytime stream tcp nowait root internal +#time stream tcp nowait root internal + +#:STANDARD: These are standard services. + +#:BSD: Shell, login, exec and talk are BSD protocols. +talk dgram udp wait nobody.tty /usr/sbin/tcpd in.talkd +ntalk dgram udp wait nobody.tty /usr/sbin/tcpd in.ntalkd + +#:MAIL: Mail, news and uucp services. + +#:INFO: Info services +finger stream tcp nowait efingerd /usr/sbin/tcpd /usr/sbin/efingerd -fi +ident stream tcp nowait identd /usr/sbin/ident2 ident2 -i -n + +#:BOOT: TFTP service is provided primarily for booting. Most sites +# run this only on machines acting as "boot servers." + +#:RPC: RPC based services + +#:HAM-RADIO: amateur-radio services + +#:OTHER: Other services +#gopher stream tcp nowait nobody /usr/sbin/gophernicus gophernicus -h envs.net -nv -o UTF-8 +gopher stream tcp nowait nobody /usr/sbin/gophernicus gophernicus -h envs.net -nv -r /var/gopher/envs.net -o UTF-8 diff --git a/etc/etc/inputrc b/etc/etc/inputrc new file mode 100644 index 0000000..1ebf533 --- /dev/null +++ b/etc/etc/inputrc @@ -0,0 +1,67 @@ +# /etc/inputrc - global inputrc for libreadline +# See readline(3readline) and `info rluserman' for more information. + +# Be 8 bit clean. +set input-meta on +set output-meta on + +# To allow the use of 8bit-characters like the german umlauts, uncomment +# the line below. However this makes the meta key not work as a meta key, +# which is annoying to those which don't need to type in 8-bit characters. + +# set convert-meta off + +# try to enable the application keypad when it is called. Some systems +# need this to enable the arrow keys. +# set enable-keypad on + +# see /usr/share/doc/bash/inputrc.arrows for other codes of arrow keys + +# do not bell on tab-completion +set bell-style none +# set bell-style visible + +# some defaults / modifications for the emacs mode +$if mode=emacs + +# allow the use of the Home/End keys +"\e[1~": beginning-of-line +"\e[4~": end-of-line + +# allow the use of the Delete/Insert keys +"\e[3~": delete-char +"\e[2~": quoted-insert + +# mappings for "page up" and "page down" to step to the beginning/end +# of the history +# "\e[5~": beginning-of-history +# "\e[6~": end-of-history + +# alternate mappings for "page up" and "page down" to search the history +"\e[5~": history-search-backward +"\e[6~": history-search-forward + +# mappings for Ctrl-left-arrow and Ctrl-right-arrow for word moving +"\e[1;5C": forward-word +"\e[1;5D": backward-word +"\e[5C": forward-word +"\e[5D": backward-word +"\e\e[C": forward-word +"\e\e[D": backward-word + +$if term=rxvt +"\e[7~": beginning-of-line +"\e[8~": end-of-line +"\eOc": forward-word +"\eOd": backward-word +$endif + +# for non RH/Debian xterm, can't hurt for RH/Debian xterm +# "\eOH": beginning-of-line +# "\eOF": end-of-line + +# for freebsd console +# "\e[H": beginning-of-line +# "\e[F": end-of-line + +$endif diff --git a/etc/etc/nanorc b/etc/etc/nanorc new file mode 100644 index 0000000..16fd344 --- /dev/null +++ b/etc/etc/nanorc @@ -0,0 +1,272 @@ +## Sample initialization file for GNU nano. +## +## Please note that you must have configured nano with --enable-nanorc +## for this file to be read! Also note that this file should not be in +## DOS or Mac format, and that characters specially interpreted by the +## shell should not be escaped here. +## +## To make sure an option is disabled, use "unset