summaryrefslogtreecommitdiffstats
path: root/tv/2configs
diff options
context:
space:
mode:
Diffstat (limited to 'tv/2configs')
-rw-r--r--tv/2configs/AO753.nix39
-rw-r--r--tv/2configs/CAC-CentOS-7-64bit.nix47
-rw-r--r--tv/2configs/CAC-Developer-1.nix6
-rw-r--r--tv/2configs/CAC-Developer-2.nix6
-rw-r--r--tv/2configs/base.nix187
-rw-r--r--tv/2configs/bash_completion.sh779
-rw-r--r--tv/2configs/charybdis.nix605
-rw-r--r--tv/2configs/consul-client.nix9
-rw-r--r--tv/2configs/consul-server.nix21
-rw-r--r--tv/2configs/cryptoroot.nix4
-rw-r--r--tv/2configs/exim-retiolum.nix126
-rw-r--r--tv/2configs/exim-smarthost.nix475
-rw-r--r--tv/2configs/git.nix90
-rw-r--r--tv/2configs/mail-client.nix14
-rw-r--r--tv/2configs/smartd.nix17
-rw-r--r--tv/2configs/synaptics.nix14
-rw-r--r--tv/2configs/urlwatch.nix51
-rw-r--r--tv/2configs/urxvt.nix24
-rw-r--r--tv/2configs/w110er.nix42
-rw-r--r--tv/2configs/xserver.nix41
20 files changed, 2597 insertions, 0 deletions
diff --git a/tv/2configs/AO753.nix b/tv/2configs/AO753.nix
new file mode 100644
index 000000000..96167ce01
--- /dev/null
+++ b/tv/2configs/AO753.nix
@@ -0,0 +1,39 @@
+{ config, pkgs, ... }:
+
+{
+ imports = [
+ ../2configs/smartd.nix
+ ];
+
+ boot.loader.grub = {
+ device = "/dev/sda";
+ splashImage = null;
+ };
+
+ boot.initrd.availableKernelModules = [
+ "ahci"
+ ];
+
+ boot.kernelModules = [
+ "kvm-intel"
+ "wl"
+ ];
+
+ boot.extraModulePackages = [
+ config.boot.kernelPackages.broadcom_sta
+ ];
+
+ networking.wireless.enable = true;
+
+ services.logind.extraConfig = ''
+ HandleHibernateKey=ignore
+ HandleLidSwitch=ignore
+ HandlePowerKey=ignore
+ HandleSuspendKey=ignore
+ '';
+
+ nixpkgs.config = {
+ allowUnfree = false;
+ allowUnfreePredicate = (x: pkgs.lib.hasPrefix "broadcom-sta-" x.name);
+ };
+}
diff --git a/tv/2configs/CAC-CentOS-7-64bit.nix b/tv/2configs/CAC-CentOS-7-64bit.nix
new file mode 100644
index 000000000..168d1d97b
--- /dev/null
+++ b/tv/2configs/CAC-CentOS-7-64bit.nix
@@ -0,0 +1,47 @@
+_:
+
+{
+ boot.loader.grub = {
+ device = "/dev/sda";
+ splashImage = null;
+ };
+
+ boot.initrd.availableKernelModules = [
+ "ata_piix"
+ "vmw_pvscsi"
+ ];
+
+ fileSystems."/" = {
+ device = "/dev/centos/root";
+ fsType = "xfs";
+ };
+
+ fileSystems."/boot" = {
+ device = "/dev/sda1";
+ fsType = "xfs";
+ };
+
+ swapDevices = [
+ { device = "/dev/centos/swap"; }
+ ];
+
+ users.extraGroups = {
+ # ● systemd-tmpfiles-setup.service - Create Volatile Files and Directories
+ # Loaded: loaded (/nix/store/2l33gg7nmncqkpysq9f5fxyhlw6ncm2j-systemd-217/example/systemd/system/systemd-tmpfiles-setup.service)
+ # Active: failed (Result: exit-code) since Mon 2015-03-16 10:29:18 UTC; 4s ago
+ # Docs: man:tmpfiles.d(5)
+ # man:systemd-tmpfiles(8)
+ # Process: 19272 ExecStart=/nix/store/2l33gg7nmncqkpysq9f5fxyhlw6ncm2j-systemd-217/bin/systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev (code=exited, status=1/FAILURE)
+ # Main PID: 19272 (code=exited, status=1/FAILURE)
+ #
+ # Mar 16 10:29:17 cd systemd-tmpfiles[19272]: [/usr/lib/tmpfiles.d/legacy.conf:26] Unknown group 'lock'.
+ # Mar 16 10:29:18 cd systemd-tmpfiles[19272]: Two or more conflicting lines for /var/log/journal configured, ignoring.
+ # Mar 16 10:29:18 cd systemd-tmpfiles[19272]: Two or more conflicting lines for /var/log/journal/7b35116927d74ea58785e00b47ac0f0d configured, ignoring.
+ # Mar 16 10:29:18 cd systemd[1]: systemd-tmpfiles-setup.service: main process exited, code=exited, status=1/FAILURE
+ # Mar 16 10:29:18 cd systemd[1]: Failed to start Create Volatile Files and Directories.
+ # Mar 16 10:29:18 cd systemd[1]: Unit systemd-tmpfiles-setup.service entered failed state.
+ # Mar 16 10:29:18 cd systemd[1]: systemd-tmpfiles-setup.service failed.
+ # warning: error(s) occured while switching to the new configuration
+ lock.gid = 10001;
+ };
+}
diff --git a/tv/2configs/CAC-Developer-1.nix b/tv/2configs/CAC-Developer-1.nix
new file mode 100644
index 000000000..37bc32afb
--- /dev/null
+++ b/tv/2configs/CAC-Developer-1.nix
@@ -0,0 +1,6 @@
+_:
+
+{
+ nix.maxJobs = 1;
+ sound.enable = false;
+}
diff --git a/tv/2configs/CAC-Developer-2.nix b/tv/2configs/CAC-Developer-2.nix
new file mode 100644
index 000000000..fedb808df
--- /dev/null
+++ b/tv/2configs/CAC-Developer-2.nix
@@ -0,0 +1,6 @@
+_:
+
+{
+ nix.maxJobs = 2;
+ sound.enable = false;
+}
diff --git a/tv/2configs/base.nix b/tv/2configs/base.nix
new file mode 100644
index 000000000..997d4c235
--- /dev/null
+++ b/tv/2configs/base.nix
@@ -0,0 +1,187 @@
+{ config, lib, pkgs, ... }:
+
+with builtins;
+with lib;
+
+let
+ # "7.4.335" -> "74"
+ majmin = x: concatStrings (take 2 (splitString "." x));
+in
+
+{
+ krebs.enable = true;
+
+ networking.hostName = config.krebs.build.host.name;
+
+ imports = [
+ {
+ users.extraUsers =
+ mapAttrs (_: h: { hashedPassword = h; })
+ (import /root/src/secrets/hashedPasswords.nix);
+ }
+ {
+ users.defaultUserShell = "/run/current-system/sw/bin/bash";
+ users.mutableUsers = false;
+ }
+ {
+ users.extraUsers = {
+ root = {
+ openssh.authorizedKeys.keys = [
+ config.krebs.users.tv.pubkey
+ ];
+ };
+ tv = {
+ uid = 1337;
+ group = "users";
+ home = "/home/tv";
+ createHome = true;
+ useDefaultShell = true;
+ extraGroups = [
+ "audio"
+ "video"
+ "wheel"
+ ];
+ openssh.authorizedKeys.keys = [
+ config.krebs.users.tv.pubkey
+ ];
+ };
+ };
+ }
+ {
+ security.sudo.extraConfig = ''
+ Defaults mailto="${config.krebs.users.tv.mail}"
+ '';
+ time.timeZone = "Europe/Berlin";
+ }
+ {
+ # TODO check if both are required:
+ nix.chrootDirs = [ "/etc/protocols" pkgs.iana_etc.outPath ];
+
+ nix.trustedBinaryCaches = [
+ "https://cache.nixos.org"
+ "http://cache.nixos.org"
+ "http://hydra.nixos.org"
+ ];
+
+ nix.useChroot = true;
+ }
+ {
+ # oldvim
+ environment.systemPackages = with pkgs; [
+ vim
+ ];
+
+ environment.etc."vim/vimrc".text = ''
+ set nocp
+ '';
+
+ environment.etc."vim/vim${majmin pkgs.vim.version}".source =
+ "${pkgs.vim}/share/vim/vim${majmin pkgs.vim.version}";
+
+ # multiple-definition-problem when defining environment.variables.EDITOR
+ environment.extraInit = ''
+ EDITOR=vim
+ '';
+
+ environment.variables.VIM = "/etc/vim";
+ }
+ {
+ environment.systemPackages = with pkgs; [
+ rxvt_unicode.terminfo
+ ];
+
+ environment.shellAliases = {
+ # alias cal='cal -m3'
+ gp = "${pkgs.pari}/bin/gp -q";
+ df = "df -h";
+ du = "du -h";
+ # alias grep='grep --color=auto'
+
+ # TODO alias cannot contain #\'
+ # "ps?" = "ps ax | head -n 1;ps ax | fgrep -v ' grep --color=auto ' | grep";
+
+ # alias la='ls -lA'
+ lAtr = "ls -lAtr";
+ # alias ll='ls -l'
+ ls = "ls -h --color=auto --group-directories-first";
+ # alias vim='vim -p'
+ # alias vi='vim'
+ # alias view='vim -R'
+ dmesg = "dmesg -L --reltime";
+ };
+
+ programs.bash = {
+ interactiveShellInit = ''
+ HISTCONTROL='erasedups:ignorespace'
+ HISTSIZE=65536
+ HISTFILESIZE=$HISTSIZE
+
+ shopt -s checkhash
+ shopt -s histappend histreedit histverify
+ shopt -s no_empty_cmd_completion
+ complete -d cd
+
+ ${readFile ./bash_completion.sh}
+
+ # TODO source bridge
+ '';
+ promptInit = ''
+ case $UID in
+ 0)
+ PS1='\[\e[1;31m\]\w\[\e[0m\] '
+ ;;
+ 1337)
+ PS1='\[\e[1;32m\]\w\[\e[0m\] '
+ ;;
+ *)
+ PS1='\[\e[1;35m\]\u \[\e[1;32m\]\w\[\e[0m\] '
+ ;;
+ esac
+ if test -n "$SSH_CLIENT"; then
+ PS1='\[\e[35m\]\h'" $PS1"
+ fi
+ if test -n "$SSH_AGENT_PID"; then
+ PS1="ssh-agent[$SSH_AGENT_PID] $PS1"
+ fi
+ '';
+ };
+
+ programs.ssh.startAgent = false;
+ }
+
+ {
+ nixpkgs.config.packageOverrides = pkgs:
+ {
+ nano = pkgs.runCommand "empty" {} "mkdir -p $out";
+ };
+
+ services.cron.enable = false;
+ services.nscd.enable = false;
+ services.ntp.enable = false;
+ }
+
+ {
+ boot.kernel.sysctl = {
+ # Enable IPv6 Privacy Extensions
+ "net.ipv6.conf.all.use_tempaddr" = 2;
+ "net.ipv6.conf.default.use_tempaddr" = 2;
+ };
+ }
+
+ {
+ services.openssh = {
+ enable = true;
+ hostKeys = [
+ { type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; }
+ ];
+ };
+ }
+
+ {
+ # TODO: exim
+ security.setuidPrograms = [
+ "sendmail" # for sudo
+ ];
+ }
+ ];
+}
diff --git a/tv/2configs/bash_completion.sh b/tv/2configs/bash_completion.sh
new file mode 100644
index 000000000..537484fb9
--- /dev/null
+++ b/tv/2configs/bash_completion.sh
@@ -0,0 +1,779 @@
+
+# Expand variable starting with tilde (~)
+# We want to expand ~foo/... to /home/foo/... to avoid problems when
+# word-to-complete starting with a tilde is fed to commands and ending up
+# quoted instead of expanded.
+# Only the first portion of the variable from the tilde up to the first slash
+# (~../) is expanded. The remainder of the variable, containing for example
+# a dollar sign variable ($) or asterisk (*) is not expanded.
+# Example usage:
+#
+# $ v="~"; __expand_tilde_by_ref v; echo "$v"
+#
+# Example output:
+#
+# v output
+# -------- ----------------
+# ~ /home/user
+# ~foo/bar /home/foo/bar
+# ~foo/$HOME /home/foo/$HOME
+# ~foo/a b /home/foo/a b
+# ~foo/* /home/foo/*
+#
+# @param $1 Name of variable (not the value of the variable) to expand
+__expand_tilde_by_ref()
+{
+ # Does $1 start with tilde (~)?
+ if [[ ${!1} == \~* ]]; then
+ # Does $1 contain slash (/)?
+ if [[ ${!1} == */* ]]; then
+ # Yes, $1 contains slash;
+ # 1: Remove * including and after first slash (/), i.e. "~a/b"
+ # becomes "~a". Double quotes allow eval.
+ # 2: Remove * before the first slash (/), i.e. "~a/b"
+ # becomes "b". Single quotes prevent eval.
+ # +-----1----+ +---2----+
+ eval $1="${!1/%\/*}"/'${!1#*/}'
+ else
+ # No, $1 doesn't contain slash
+ eval $1="${!1}"
+ fi
+ fi
+} # __expand_tilde_by_ref()
+
+
+# Get the word to complete.
+# This is nicer than ${COMP_WORDS[$COMP_CWORD]}, since it handles cases
+# where the user is completing in the middle of a word.
+# (For example, if the line is "ls foobar",
+# and the cursor is here --------> ^
+# @param $1 string Characters out of $COMP_WORDBREAKS which should NOT be
+# considered word breaks. This is useful for things like scp where
+# we want to return host:path and not only path, so we would pass the
+# colon (:) as $1 in this case.
+# @param $2 integer Index number of word to return, negatively offset to the
+# current word (default is 0, previous is 1), respecting the exclusions
+# given at $1. For example, `_get_cword "=:" 1' returns the word left of
+# the current word, respecting the exclusions "=:".
+# @deprecated Use `_get_comp_words_by_ref cur' instead
+# @see _get_comp_words_by_ref()
+_get_cword()
+{
+ local LC_CTYPE=C
+ local cword words
+ __reassemble_comp_words_by_ref "$1" words cword
+
+ # return previous word offset by $2
+ if [[ ${2//[^0-9]/} ]]; then
+ printf "%s" "${words[cword-$2]}"
+ elif [[ "${#words[cword]}" -eq 0 || "$COMP_POINT" == "${#COMP_LINE}" ]]; then
+ printf "%s" "${words[cword]}"
+ else
+ local i
+ local cur="$COMP_LINE"
+ local index="$COMP_POINT"
+ for (( i = 0; i <= cword; ++i )); do
+ while [[
+ # Current word fits in $cur?
+ "${#cur}" -ge ${#words[i]} &&
+ # $cur doesn't match cword?
+ "${cur:0:${#words[i]}}" != "${words[i]}"
+ ]]; do
+ # Strip first character
+ cur="${cur:1}"
+ # Decrease cursor position
+ ((index--))
+ done
+
+ # Does found word matches cword?
+ if [[ "$i" -lt "$cword" ]]; then
+ # No, cword lies further;
+ local old_size="${#cur}"
+ cur="${cur#${words[i]}}"
+ local new_size="${#cur}"
+ index=$(( index - old_size + new_size ))
+ fi
+ done
+
+ if [[ "${words[cword]:0:${#cur}}" != "$cur" ]]; then
+ # We messed up! At least return the whole word so things
+ # keep working
+ printf "%s" "${words[cword]}"
+ else
+ printf "%s" "${cur:0:$index}"
+ fi
+ fi
+} # _get_cword()
+
+
+# Get word previous to the current word.
+# This is a good alternative to `prev=${COMP_WORDS[COMP_CWORD-1]}' because bash4
+# will properly return the previous word with respect to any given exclusions to
+# COMP_WORDBREAKS.
+# @deprecated Use `_get_comp_words_by_ref cur prev' instead
+# @see _get_comp_words_by_ref()
+#
+_get_pword()
+{
+ if [[ $COMP_CWORD -ge 1 ]]; then
+ _get_cword "${@:-}" 1
+ fi
+}
+
+
+
+# Complete variables.
+# @return True (0) if variables were completed,
+# False (> 0) if not.
+_variables()
+{
+ if [[ $cur =~ ^(\$\{?)([A-Za-z0-9_]*)$ ]]; then
+ [[ $cur == *{* ]] && local suffix=} || local suffix=
+ COMPREPLY+=( $( compgen -P ${BASH_REMATCH[1]} -S "$suffix" -v -- \
+ "${BASH_REMATCH[2]}" ) )
+ return 0
+ fi
+ return 1
+}
+
+# Assign variable one scope above the caller
+# Usage: local "$1" && _upvar $1 "value(s)"
+# Param: $1 Variable name to assign value to
+# Param: $* Value(s) to assign. If multiple values, an array is
+# assigned, otherwise a single value is assigned.
+# NOTE: For assigning multiple variables, use '_upvars'. Do NOT
+# use multiple '_upvar' calls, since one '_upvar' call might
+# reassign a variable to be used by another '_upvar' call.
+# See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference
+_upvar()
+{
+ if unset -v "$1"; then # Unset & validate varname
+ if (( $# == 2 )); then
+ eval $1=\"\$2\" # Return single value
+ else
+ eval $1=\(\"\${@:2}\"\) # Return array
+ fi
+ fi
+}
+
+# Assign variables one scope above the caller
+# Usage: local varname [varname ...] &&
+# _upvars [-v varname value] | [-aN varname [value ...]] ...
+# Available OPTIONS:
+# -aN Assign next N values to varname as array
+# -v Assign single value to varname
+# Return: 1 if error occurs
+# See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference
+_upvars()
+{
+ if ! (( $# )); then
+ echo "${FUNCNAME[0]}: usage: ${FUNCNAME[0]} [-v varname"\
+ "value] | [-aN varname [value ...]] ..." 1>&2
+ return 2
+ fi
+ while (( $# )); do
+ case $1 in
+ -a*)
+ # Error checking
+ [[ ${1#-a} ]] || { echo "bash: ${FUNCNAME[0]}: \`$1': missing"\
+ "number specifier" 1>&2; return 1; }
+ printf %d "${1#-a}" &> /dev/null || { echo "bash:"\
+ "${FUNCNAME[0]}: \`$1': invalid number specifier" 1>&2
+ return 1; }
+ # Assign array of -aN elements
+ [[ "$2" ]] && unset -v "$2" && eval $2=\(\"\${@:3:${1#-a}}\"\) &&
+ shift $((${1#-a} + 2)) || { echo "bash: ${FUNCNAME[0]}:"\
+ "\`$1${2+ }$2': missing argument(s)" 1>&2; return 1; }
+ ;;
+ -v)
+ # Assign single value
+ [[ "$2" ]] && unset -v "$2" && eval $2=\"\$3\" &&
+ shift 3 || { echo "bash: ${FUNCNAME[0]}: $1: missing"\
+ "argument(s)" 1>&2; return 1; }
+ ;;
+ *)
+ echo "bash: ${FUNCNAME[0]}: $1: invalid option" 1>&2
+ return 1 ;;
+ esac
+ done
+}
+
+# @param $1 exclude Characters out of $COMP_WORDBREAKS which should NOT be
+# considered word breaks. This is useful for things like scp where
+# we want to return host:path and not only path, so we would pass the
+# colon (:) as $1 in this case.
+# @param $2 words Name of variable to return words to
+# @param $3 cword Name of variable to return cword to
+# @param $4 cur Name of variable to return current word to complete to
+# @see __reassemble_comp_words_by_ref()
+__get_cword_at_cursor_by_ref()
+{
+ local cword words=()
+ __reassemble_comp_words_by_ref "$1" words cword
+
+ local i cur index=$COMP_POINT lead=${COMP_LINE:0:$COMP_POINT}
+ # Cursor not at position 0 and not leaded by just space(s)?
+ if [[ $index -gt 0 && ( $lead && ${lead//[[:space:]]} ) ]]; then
+ cur=$COMP_LINE
+ for (( i = 0; i <= cword; ++i )); do
+ while [[
+ # Current word fits in $cur?
+ ${#cur} -ge ${#words[i]} &&
+ # $cur doesn't match cword?
+ "${cur:0:${#words[i]}}" != "${words[i]}"
+ ]]; do
+ # Strip first character
+ cur="${cur:1}"
+ # Decrease cursor position
+ ((index--))
+ done
+
+ # Does found word match cword?
+ if [[ $i -lt $cword ]]; then
+ # No, cword lies further;
+ local old_size=${#cur}
+ cur="${cur#"${words[i]}"}"
+ local new_size=${#cur}
+ index=$(( index - old_size + new_size ))
+ fi
+ done
+ # Clear $cur if just space(s)
+ [[ $cur && ! ${cur//[[:space:]]} ]] && cur=
+ # Zero $index if negative
+ [[ $index -lt 0 ]] && index=0
+ fi
+
+ local "$2" "$3" "$4" && _upvars -a${#words[@]} $2 "${words[@]}" \
+ -v $3 "$cword" -v $4 "${cur:0:$index}"
+}
+
+# Reassemble command line words, excluding specified characters from the
+# list of word completion separators (COMP_WORDBREAKS).
+# @param $1 chars Characters out of $COMP_WORDBREAKS which should
+# NOT be considered word breaks. This is useful for things like scp where
+# we want to return host:path and not only path, so we would pass the
+# colon (:) as $1 here.
+# @param $2 words Name of variable to return words to
+# @param $3 cword Name of variable to return cword to
+#
+__reassemble_comp_words_by_ref()
+{
+ local exclude i j line ref
+ # Exclude word separator characters?
+ if [[ $1 ]]; then
+ # Yes, exclude word separator characters;
+ # Exclude only those characters, which were really included
+ exclude="${1//[^$COMP_WORDBREAKS]}"
+ fi
+
+ # Default to cword unchanged
+ eval $3=$COMP_CWORD
+ # Are characters excluded which were former included?
+ if [[ $exclude ]]; then
+ # Yes, list of word completion separators has shrunk;
+ line=$COMP_LINE
+ # Re-assemble words to complete
+ for (( i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
+ # Is current word not word 0 (the command itself) and is word not
+ # empty and is word made up of just word separator characters to
+ # be excluded and is current word not preceded by whitespace in
+ # original line?
+ while [[ $i -gt 0 && ${COMP_WORDS[$i]} == +([$exclude]) ]]; do
+ # Is word separator not preceded by whitespace in original line
+ # and are we not going to append to word 0 (the command
+ # itself), then append to current word.
+ [[ $line != [$' \t']* ]] && (( j >= 2 )) && ((j--))
+ # Append word separator to current or new word
+ ref="$2[$j]"
+ eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
+ # Indicate new cword
+ [[ $i == $COMP_CWORD ]] && eval $3=$j
+ # Remove optional whitespace + word separator from line copy
+ line=${line#*"${COMP_WORDS[$i]}"}
+ # Start new word if word separator in original line is
+ # followed by whitespace.
+ [[ $line == [$' \t']* ]] && ((j++))
+ # Indicate next word if available, else end *both* while and
+ # for loop
+ (( $i < ${#COMP_WORDS[@]} - 1)) && ((i++)) || break 2
+ done
+ # Append word to current word
+ ref="$2[$j]"
+ eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
+ # Remove optional whitespace + word from line copy
+ line=${line#*"${COMP_WORDS[i]}"}
+ # Indicate new cword
+ [[ $i == $COMP_CWORD ]] && eval $3=$j
+ done
+ [[ $i == $COMP_CWORD ]] && eval $3=$j
+ else
+ # No, list of word completions separators hasn't changed;
+ eval $2=\( \"\${COMP_WORDS[@]}\" \)
+ fi
+} # __reassemble_comp_words_by_ref()
+
+
+# If the word-to-complete contains a colon (:), left-trim COMPREPLY items with
+# word-to-complete.
+# With a colon in COMP_WORDBREAKS, words containing
+# colons are always completed as entire words if the word to complete contains
+# a colon. This function fixes this, by removing the colon-containing-prefix
+# from COMPREPLY items.
+# The preferred solution is to remove the colon (:) from COMP_WORDBREAKS in
+# your .bashrc:
+#
+# # Remove colon (:) from list of word completion separators
+# COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
+#
+# See also: Bash FAQ - E13) Why does filename completion misbehave if a colon
+# appears in the filename? - http://tiswww.case.edu/php/chet/bash/FAQ
+# @param $1 current word to complete (cur)
+# @modifies global array $COMPREPLY
+#
+__ltrim_colon_completions()
+{
+ if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
+ # Remove colon-word prefix from COMPREPLY items
+ local colon_word=${1%"${1##*:}"}
+ local i=${#COMPREPLY[*]}
+ while [[ $((--i)) -ge 0 ]]; do
+ COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
+ done
+ fi
+} # __ltrim_colon_completions()
+
+
+# NOTE: Using this function as a helper function is deprecated. Use
+# `_known_hosts_real' instead.
+_known_hosts()
+{
+ local cur prev words cword
+ _init_completion -n : || return
+
+ # NOTE: Using `_known_hosts' as a helper function and passing options
+ # to `_known_hosts' is deprecated: Use `_known_hosts_real' instead.
+ local options
+ [[ "$1" == -a || "$2" == -a ]] && options=-a
+ [[ "$1" == -c || "$2" == -c ]] && options+=" -c"
+ _known_hosts_real $options -- "$cur"
+} # _known_hosts()
+
+
+# Helper function for completing _known_hosts.
+# This function performs host completion based on ssh's config and known_hosts
+# files, as well as hostnames reported by avahi-browse if
+# COMP_KNOWN_HOSTS_WITH_AVAHI is set to a non-empty value. Also hosts from
+# HOSTFILE (compgen -A hostname) are added, unless
+# COMP_KNOWN_HOSTS_WITH_HOSTFILE is set to an empty value.
+# Usage: _known_hosts_real [OPTIONS] CWORD
+# Options: -a Use aliases
+# -c Use `:' suffix
+# -F configfile Use `configfile' for configuration settings
+# -p PREFIX Use PREFIX
+# Return: Completions, starting with CWORD, are added to COMPREPLY[]
+_known_hosts_real()
+{
+ local configfile flag prefix
+ local cur curd awkcur user suffix aliases i host
+ local -a kh khd config
+
+ local OPTIND=1
+ while getopts "acF:p:" flag "$@"; do
+ case $flag in
+ a) aliases='yes' ;;
+ c) suffix=':' ;;
+ F) configfile=$OPTARG ;;
+ p) prefix=$OPTARG ;;
+ esac
+ done
+ [[ $# -lt $OPTIND ]] && echo "error: $FUNCNAME: missing mandatory argument CWORD"
+ cur=${!OPTIND}; let "OPTIND += 1"
+ [[ $# -ge $OPTIND ]] && echo "error: $FUNCNAME("$@"): unprocessed arguments:"\
+ $(while [[ $# -ge $OPTIND ]]; do printf '%s\n' ${!OPTIND}; shift; done)
+
+ [[ $cur == *@* ]] && user=${cur%@*}@ && cur=${cur#*@}
+ kh=()
+
+ # ssh config files
+ if [[ -n $configfile ]]; then
+ [[ -r $configfile ]] && config+=( "$configfile" )
+ else
+ for i in /etc/ssh/ssh_config ~/.ssh/config ~/.ssh2/config; do
+ [[ -r $i ]] && config+=( "$i" )
+ done
+ fi
+
+ # Known hosts files from configs
+ if [[ ${#config[@]} -gt 0 ]]; then
+ local OIFS=$IFS IFS=$'\n' j
+ local -a tmpkh
+ # expand paths (if present) to global and user known hosts files
+ # TODO(?): try to make known hosts files with more than one consecutive
+ # spaces in their name work (watch out for ~ expansion
+ # breakage! Alioth#311595)
+ tmpkh=( $( awk 'sub("^[ \t]*([Gg][Ll][Oo][Bb][Aa][Ll]|[Uu][Ss][Ee][Rr])[Kk][Nn][Oo][Ww][Nn][Hh][Oo][Ss][Tt][Ss][Ff][Ii][Ll][Ee][ \t]+", "") { print $0 }' "${config[@]}" | sort -u ) )
+ IFS=$OIFS
+ for i in "${tmpkh[@]}"; do
+ # First deal with quoted entries...
+ while [[ $i =~ ^([^\"]*)\"([^\"]*)\"(.*)$ ]]; do
+ i=${BASH_REMATCH[1]}${BASH_REMATCH[3]}
+ j=${BASH_REMATCH[2]}
+ __expand_tilde_by_ref j # Eval/expand possible `~' or `~user'
+ [[ -r $j ]] && kh+=( "$j" )
+ done
+ # ...and then the rest.
+ for j in $i; do
+ __expand_tilde_by_ref j # Eval/expand possible `~' or `~user'
+ [[ -r $j ]] && kh+=( "$j" )
+ done
+ done
+ fi
+
+
+ if [[ -z $configfile ]]; then
+ # Global and user known_hosts files
+ for i in /etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2 \
+ /etc/known_hosts /etc/known_hosts2 ~/.ssh/known_hosts \
+ ~/.ssh/known_hosts2; do
+ [[ -r $i ]] && kh+=( "$i" )
+ done
+ for i in /etc/ssh2/knownhosts ~/.ssh2/hostkeys; do
+ [[ -d $i ]] && khd+=( "$i"/*pub )
+ done
+ fi
+
+ # If we have known_hosts files to use
+ if [[ ${#kh[@]} -gt 0 || ${#khd[@]} -gt 0 ]]; then
+ # Escape slashes and dots in paths for awk
+ awkcur=${cur//\//\\\/}
+ awkcur=${awkcur//\./\\\.}
+ curd=$awkcur
+
+ if [[ "$awkcur" == [0-9]*[.:]* ]]; then
+ # Digits followed by a dot or a colon - just search for that
+ awkcur="^$awkcur[.:]*"
+ elif [[ "$awkcur" == [0-9]* ]]; then
+ # Digits followed by no dot or colon - search for digits followed
+ # by a dot or a colon
+ awkcur="^$awkcur.*[.:]"
+ elif [[ -z $awkcur ]]; then
+ # A blank - search for a dot, a colon, or an alpha character
+ awkcur="[a-z.:]"
+ else
+ awkcur="^$awkcur"
+ fi
+
+ if [[ ${#kh[@]} -gt 0 ]]; then
+ # FS needs to look for a comma separated list
+ COMPREPLY+=( $( awk 'BEGIN {FS=","}
+ /^\s*[^|\#]/ {
+ sub("^@[^ ]+ +", ""); \
+ sub(" .*$", ""); \
+ for (i=1; i<=NF; ++i) { \
+ sub("^\\[", "", $i); sub("\\](:[0-9]+)?$", "", $i); \
+ if ($i !~ /[*?]/ && $i ~ /'"$awkcur"'/) {print $i} \
+ }}' "${kh[@]}" 2>/dev/null ) )
+ fi
+ if [[ ${#khd[@]} -gt 0 ]]; then
+ # Needs to look for files called
+ # .../.ssh2/key_22_<hostname>.pub
+ # dont fork any processes, because in a cluster environment,
+ # there can be hundreds of hostkeys
+ for i in "${khd[@]}" ; do
+ if [[ "$i" == *key_22_$curd*.pub && -r "$i" ]]; then
+ host=${i/#*key_22_/}
+ host=${host/%.pub/}
+ COMPREPLY+=( $host )
+ fi
+ done
+ fi
+
+ # apply suffix and prefix
+ for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
+ COMPREPLY[i]=$prefix$user${COMPREPLY[i]}$suffix
+ done
+ fi
+
+ # append any available aliases from config files
+ if [[ ${#config[@]} -gt 0 && -n "$aliases" ]]; then
+ local hosts=$( sed -ne 's/^[ \t]*[Hh][Oo][Ss][Tt]\([Nn][Aa][Mm][Ee]\)\{0,1\}['"$'\t '"']\{1,\}\([^#*?]*\)\(#.*\)\{0,1\}$/\2/p' "${config[@]}" )
+ COMPREPLY+=( $( compgen -P "$prefix$user" \
+ -S "$suffix" -W "$hosts" -- "$cur" ) )
+ fi
+
+ # Add hosts reported by avahi-browse, if desired and it's available.
+ if [[ ${COMP_KNOWN_HOSTS_WITH_AVAHI:-} ]] && \
+ type avahi-browse &>/dev/null; then
+ # The original call to avahi-browse also had "-k", to avoid lookups
+ # into avahi's services DB. We don't need the name of the service, and
+ # if it contains ";", it may mistify the result. But on Gentoo (at
+ # least), -k wasn't available (even if mentioned in the manpage) some
+ # time ago, so...
+ COMPREPLY+=( $( compgen -P "$prefix$user" -S "$suffix" -W \
+ "$( avahi-browse -cpr _workstation._tcp 2>/dev/null | \
+ awk -F';' '/^=/ { print $7 }' | sort -u )" -- "$cur" ) )
+ fi
+
+ # Add hosts reported by ruptime.
+ COMPREPLY+=( $( compgen -W \
+ "$( ruptime 2>/dev/null | awk '!/^ruptime:/ { print $1 }' )" \
+ -- "$cur" ) )
+
+ # Add results of normal hostname completion, unless
+ # `COMP_KNOWN_HOSTS_WITH_HOSTFILE' is set to an empty value.
+ if [[ -n ${COMP_KNOWN_HOSTS_WITH_HOSTFILE-1} ]]; then
+ COMPREPLY+=(
+ $( compgen -A hostname -P "$prefix$user" -S "$suffix" -- "$cur" ) )
+ fi
+
+ __ltrim_colon_completions "$prefix$user$cur"
+
+ return 0
+} # _known_hosts_real()
+
+
+# Get the word to complete and optional previous words.
+# This is nicer than ${COMP_WORDS[$COMP_CWORD]}, since it handles cases
+# where the user is completing in the middle of a word.
+# (For example, if the line is "ls foobar",
+# and the cursor is here --------> ^
+# Also one is able to cross over possible wordbreak characters.
+# Usage: _get_comp_words_by_ref [OPTIONS] [VARNAMES]
+# Available VARNAMES:
+# cur Return cur via $cur
+# prev Return prev via $prev
+# words Return words via $words
+# cword Return cword via $cword
+#
+# Available OPTIONS:
+# -n EXCLUDE Characters out of $COMP_WORDBREAKS which should NOT be
+# considered word breaks. This is useful for things like scp
+# where we want to return host:path and not only path, so we
+# would pass the colon (:) as -n option in this case.
+# -c VARNAME Return cur via $VARNAME
+# -p VARNAME Return prev via $VARNAME
+# -w VARNAME Return words via $VARNAME
+# -i VARNAME Return cword via $VARNAME
+#
+# Example usage:
+#
+# $ _get_comp_words_by_ref -n : cur prev
+#
+_get_comp_words_by_ref()
+{
+ local exclude flag i OPTIND=1
+ local cur cword words=()
+ local upargs=() upvars=() vcur vcword vprev vwords
+
+ while getopts "c:i:n:p:w:" flag "$@"; do
+ case $flag in
+ c) vcur=$OPTARG ;;
+ i) vcword=$OPTARG ;;
+ n) exclude=$OPTARG ;;
+ p) vprev=$OPTARG ;;
+ w) vwords=$OPTARG ;;
+ esac
+ done
+ while [[ $# -ge $OPTIND ]]; do
+ case ${!OPTIND} in
+ cur) vcur=cur ;;
+ prev) vprev=prev ;;
+ cword) vcword=cword ;;
+ words) vwords=words ;;
+ *) echo "bash: $FUNCNAME(): \`${!OPTIND}': unknown argument" \
+ 1>&2; return 1
+ esac
+ let "OPTIND += 1"
+ done
+
+ __get_cword_at_cursor_by_ref "$exclude" words cword cur
+
+ [[ $vcur ]] && { upvars+=("$vcur" ); upargs+=(-v $vcur "$cur" ); }
+ [[ $vcword ]] && { upvars+=("$vcword"); upargs+=(-v $vcword "$cword"); }
+ [[ $vprev && $cword -ge 1 ]] && { upvars+=("$vprev" ); upargs+=(-v $vprev
+ "${words[cword - 1]}"); }
+ [[ $vwords ]] && { upvars+=("$vwords"); upargs+=(-a${#words[@]} $vwords
+ "${words[@]}"); }
+
+ (( ${#upvars[@]} )) && local "${upvars[@]}" && _upvars "${upargs[@]}"
+}
+
+# Initialize completion and deal with various general things: do file
+# and variable completion where appropriate, and adjust prev, words,
+# and cword as if no redirections exist so that completions do not
+# need to deal with them. Before calling this function, make sure
+# cur, prev, words, and cword are local, ditto split if you use -s.
+#
+# Options:
+# -n EXCLUDE Passed to _get_comp_words_by_ref -n with redirection chars
+# -e XSPEC Passed to _filedir as first arg for stderr redirections
+# -o XSPEC Passed to _filedir as first arg for other output redirections
+# -i XSPEC Passed to _filedir as first arg for stdin redirections
+# -s Split long options with _split_longopt, implies -n =
+# @return True (0) if completion needs further processing,
+# False (> 0) no further processing is necessary.
+#
+_init_completion()
+{
+ local exclude= flag outx errx inx OPTIND=1
+
+ while getopts "n:e:o:i:s" flag "$@"; do
+ case $flag in
+ n) exclude+=$OPTARG ;;
+ e) errx=$OPTARG ;;
+ o) outx=$OPTARG ;;
+ i) inx=$OPTARG ;;
+ s) split=false ; exclude+== ;;
+ esac
+ done
+
+ # For some reason completion functions are not invoked at all by
+ # bash (at least as of 4.1.7) after the command line contains an
+ # ampersand so we don't get a chance to deal with redirections
+ # containing them, but if we did, hopefully the below would also
+ # do the right thing with them...
+
+ COMPREPLY=()
+ local redir="@(?([0-9])<|?([0-9&])>?(>)|>&)"
+ _get_comp_words_by_ref -n "$exclude<>&" cur prev words cword
+
+ # Complete variable names.
+ _variables && return 1
+
+ # Complete on files if current is a redirect possibly followed by a
+ # filename, e.g. ">foo", or previous is a "bare" redirect, e.g. ">".
+ if [[ $cur == $redir* || $prev == $redir ]]; then
+ local xspec
+ case $cur in
+ 2'>'*) xspec=$errx ;;
+ *'>'*) xspec=$outx ;;
+ *'<'*) xspec=$inx ;;
+ *)
+ case $prev in
+ 2'>'*) xspec=$errx ;;
+ *'>'*) xspec=$outx ;;
+ *'<'*) xspec=$inx ;;
+ esac
+ ;;
+ esac
+ cur="${cur##$redir}"
+ _filedir $xspec
+ return 1
+ fi
+
+ # Remove all redirections so completions don't have to deal with them.
+ local i skip
+ for (( i=1; i < ${#words[@]}; )); do
+ if [[ ${words[i]} == $redir* ]]; then
+ # If "bare" redirect, remove also the next word (skip=2).
+ [[ ${words[i]} == $redir ]] && skip=2 || skip=1
+ words=( "${words[@]:0:i}" "${words[@]:i+skip}" )
+ [[ $i -le $cword ]] && cword=$(( cword - skip ))
+ else
+ i=$(( ++i ))
+ fi
+ done
+
+ [[ $cword -le 0 ]] && return 1
+ prev=${words[cword-1]}
+
+ [[ ${split-} ]] && _split_longopt && split=true
+
+ return 0
+}
+
+# Try to complete -o SubOptions=
+#
+# Returns 0 if the completion was handled or non-zero otherwise.
+_ssh_suboption_check()
+{
+ # Get prev and cur words without splitting on =
+ local cureq=`_get_cword :=` preveq=`_get_pword :=`
+ if [[ $cureq == *=* && $preveq == -o ]]; then
+ _ssh_suboption $cureq
+ return $?
+ fi
+ return 1
+}
+
+_complete_ssh()
+{
+ local cur prev words cword
+ _init_completion -n : || return
+
+ local configfile
+ local -a config
+
+ _ssh_suboption_check && return 0
+
+ case $prev in
+ -F|-i|-S)
+ _filedir
+ return 0
+ ;;
+ -c)
+ _ssh_ciphers
+ return 0
+ ;;
+ -m)
+ _ssh_macs
+ return 0
+ ;;
+ -l)
+ COMPREPLY=( $( compgen -u -- "$cur" ) )
+ return 0
+ ;;
+ -O)
+ COMPREPLY=( $( compgen -W 'check forward exit stop' -- "$cur" ) )
+ return 0
+ ;;
+ -o)
+ _ssh_options
+ return 0
+ ;;
+ -w)
+ _available_interfaces
+ return 0
+ ;;
+ -b)
+ _ip_addresses
+ return 0
+ ;;
+ -D|-e|-I|-L|-p|-R|-W)
+ return 0
+ ;;
+ esac
+
+ if [[ "$cur" == -F* ]]; then
+ cur=${cur#-F}
+ _filedir
+ # Prefix completions with '-F'
+ COMPREPLY=( "${COMPREPLY[@]/#/-F}" )
+ cur=-F$cur # Restore cur
+ elif [[ "$cur" == -* ]]; then
+ COMPREPLY=( $( compgen -W '$( _parse_usage "$1" )' -- "$cur" ) )
+ else
+ # Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument
+ set -- "${words[@]}"
+ while [[ $# -gt 0 ]]; do
+ if [[ $1 == -F* ]]; then
+ if [[ ${#1} -gt 2 ]]; then
+ configfile="$(dequote "${1:2}")"
+ else
+ shift
+ [[ $1 ]] && configfile="$(dequote "$1")"
+ fi
+ break
+ fi
+ shift
+ done
+ _known_hosts_real -a -F "$configfile" "$cur"
+ if [[ $cword -ne 1 ]]; then
+ compopt -o filenames
+ COMPREPLY+=( $( compgen -c -- "$cur" ) )
+ fi
+ fi
+
+ return 0
+} &&
+shopt -u hostcomplete && complete -F _complete_ssh ssh
diff --git a/tv/2configs/charybdis.nix b/tv/2configs/charybdis.nix
new file mode 100644
index 000000000..bf45bf294
--- /dev/null
+++ b/tv/2configs/charybdis.nix
@@ -0,0 +1,605 @@
+{ config, lib, pkgs, ... }:
+
+let
+ tvpkgs = import ../5pkgs { inherit pkgs; };
+in
+
+with builtins;
+with lib;
+let
+ cfg = config.tv.charybdis;
+
+ out = {
+ options.tv.charybdis = api;
+ config = mkIf cfg.enable (mkMerge [
+ imp
+ { tv.iptables.input-retiolum-accept-new-tcp = [ 6667 6697 ]; }
+ ]);
+ };
+
+ api = {
+ enable = mkEnableOption "tv.charybdis";
+ dataDir = mkOption {
+ type = types.str;
+ default = "/var/lib/charybdis";
+ };
+ dhParams = mkOption {
+ type = types.str;
+ default = "/root/src/secrets/charybdis.dh.pem";
+ };
+ motd = mkOption {
+ type = types.str;
+ default = "/join #retiolum";
+ };
+ sslCert = mkOption {
+ type = types.path;
+ };
+ sslKey = mkOption {
+ type = types.str;
+ default = "/root/src/secrets/charybdis.key.pem";
+ };
+ };
+
+ imp = {
+ systemd.services.charybdis = {
+ wantedBy = [ "multi-user.target" ];
+ environment = {
+ BANDB_DBPATH = "${cfg.dataDir}/ban.db";
+ };
+ serviceConfig = {
+ PermissionsStartOnly = "true";
+ SyslogIdentifier = "charybdis";
+ User = user.name;
+ PrivateTmp = "true";
+ Restart = "always";
+ ExecStartPre = pkgs.writeScript "charybdis-init" ''
+ #! /bin/sh
+ mkdir -p ${cfg.dataDir}
+ chown ${user.name}: ${cfg.dataDir}
+ install -o ${user.name} -m 0400 ${cfg.sslKey} /tmp/ssl.key
+ install -o ${user.name} -m 0400 ${cfg.dhParams} /tmp/dh.pem
+ echo ${escapeShellArg cfg.motd} > /tmp/ircd.motd
+ '';
+ ExecStart = pkgs.writeScript "charybdis-service" ''
+ #! /bin/sh
+ set -euf
+ exec ${tvpkgs.charybdis}/bin/charybdis-ircd \
+ -foreground \
+ -logfile /dev/stderr \
+ -configfile ${configFile}
+ '';
+ };
+ };
+
+ users.extraUsers = singleton {
+ inherit (user) name uid;
+ };
+ };
+
+ user = {
+ name = "charybdis";
+ uid = 3748224544; # genid charybdis
+ };
+
+ configFile = toFile "charybdis-ircd.conf" ''
+ /* doc/example.conf - brief example configuration file
+ *
+ * Copyright (C) 2000-2002 Hybrid Development Team
+ * Copyright (C) 2002-2005 ircd-ratbox development team
+ * Copyright (C) 2005-2006 charybdis development team
+ *
+ * $Id: example.conf 3582 2007-11-17 21:55:48Z jilles $
+ *
+ * See reference.conf for more information.
+ */
+
+ /* Extensions */
+ #loadmodule "extensions/chm_operonly_compat.so";
+ #loadmodule "extensions/chm_quietunreg_compat.so";
+ #loadmodule "extensions/chm_sslonly_compat.so";
+ #loadmodule "extensions/createauthonly.so";
+ #loadmodule "extensions/extb_account.so";
+ #loadmodule "extensions/extb_canjoin.so";
+ #loadmodule "extensions/extb_channel.so";
+ #loadmodule "extensions/extb_extgecos.so";
+ #loadmodule "extensions/extb_oper.so";
+ #loadmodule "extensions/extb_realname.so";
+ #loadmodule "extensions/extb_server.so";
+ #loadmodule "extensions/extb_ssl.so";
+ #loadmodule "extensions/hurt.so";
+ #loadmodule "extensions/m_findforwards.so";
+ #loadmodule "extensions/m_identify.so";
+ #loadmodule "extensions/no_oper_invis.so";
+ #loadmodule "extensions/sno_farconnect.so";
+ #loadmodule "extensions/sno_globalkline.so";
+ #loadmodule "extensions/sno_globaloper.so";
+ #loadmodule "extensions/sno_whois.so";
+ loadmodule "extensions/override.so";
+
+ /*
+ * IP cloaking extensions: use ip_cloaking_4.0
+ * if you're linking 3.2 and later, otherwise use
+ * ip_cloaking.so, for compatibility with older 3.x
+ * releases.
+ */
+
+ #loadmodule "extensions/ip_cloaking_4.0.so";
+ #loadmodule "extensions/ip_cloaking.so";
+
+ serverinfo {
+ name = ${toJSON (head config.krebs.build.host.nets.retiolum.aliases)};
+ sid = "4z3";
+ description = "miep!";
+ network_name = "irc.retiolum";
+ #network_desc = "Retiolum IRC Network";
+ hub = yes;
+
+ /* On multi-homed hosts you may need the following. These define
+ * the addresses we connect from to other servers. */
+ /* for IPv4 */
+ vhost = ${concatMapStringsSep ", " toJSON config.krebs.build.host.nets.retiolum.addrs4};
+ /* for IPv6 */
+ vhost6 = ${concatMapStringsSep ", " toJSON config.krebs.build.host.nets.retiolum.addrs6};
+
+ /* ssl_private_key: our ssl private key */
+ ssl_private_key = "/tmp/ssl.key";
+
+ /* ssl_cert: certificate for our ssl server */
+ ssl_cert = ${toJSON cfg.sslCert};
+
+ /* ssl_dh_params: DH parameters, generate with openssl dhparam -out dh.pem 1024 */
+ ssl_dh_params = "/tmp/dh.pem";
+
+ /* ssld_count: number of ssld processes you want to start, if you
+ * have a really busy server, using N-1 where N is the number of
+ * cpu/cpu cores you have might be useful. A number greater than one
+ * can also be useful in case of bugs in ssld and because ssld needs
+ * two file descriptors per SSL connection.
+ */
+ ssld_count = 1;
+
+ /* default max clients: the default maximum number of clients
+ * allowed to connect. This can be changed once ircd has started by
+ * issuing:
+ * /quote set maxclients <limit>
+ */
+ default_max_clients = 1024;
+
+ /* nicklen: enforced nickname length (for this server only; must not
+ * be longer than the maximum length set while building).
+ */
+ nicklen = 30;
+ };
+
+ admin {
+ name = "tv";
+ description = "peer";
+ mail = "${config.krebs.users.tv.mail}";
+ };
+
+ log {
+ fname_userlog = "/dev/stderr";
+ fname_fuserlog = "/dev/stderr";
+ fname_operlog = "/dev/stderr";
+ fname_foperlog = "/dev/stderr";
+ fname_serverlog = "/dev/stderr";
+ fname_klinelog = "/dev/stderr";
+ fname_killlog = "/dev/stderr";
+ fname_operspylog = "/dev/stderr";
+ fname_ioerrorlog = "/dev/stderr";
+ };
+
+ /* class {} blocks MUST be specified before anything that uses them. That
+ * means they must be defined before auth {} and before connect {}.
+ */
+
+ class "krebs" {
+ ping_time = 2 minutes;
+ number_per_ident = 10;
+ number_per_ip = 2048;
+ number_per_ip_global = 4096;
+ cidr_ipv4_bitlen = 24;
+ cidr_ipv6_bitlen = 64;
+ number_per_cidr = 65536;
+ max_number = 3000;
+ sendq = 1 megabyte;
+ };
+
+ class "users" {
+ ping_time = 2 minutes;
+ number_per_ident = 10;
+ number_per_ip = 1024;
+ number_per_ip_global = 4096;
+ cidr_ipv4_bitlen = 24;
+ cidr_ipv6_bitlen = 64;
+ number_per_cidr = 65536;
+ max_number = 3000;
+ sendq = 400 kbytes;
+ };
+
+ class "opers" {
+ ping_time = 5 minutes;
+ number_per_ip = 10;
+ max_number = 1000;
+ sendq = 1 megabyte;
+ };
+
+ class "server" {
+ ping_time = 5 minutes;
+ connectfreq = 5 minutes;
+ max_number = 1;
+ sendq = 4 megabytes;
+ };
+
+ listen {
+ /* defer_accept: wait for clients to send IRC handshake data before
+ * accepting them. if you intend to use software which depends on the
+ * server replying first, such as BOPM, you should disable this feature.
+ * otherwise, you probably want to leave it on.
+ */
+ defer_accept = yes;
+
+ /* If you want to listen on a specific IP only, specify host.
+ * host definitions apply only to the following port line.
+ */
+ # XXX This is stupid because only one host is allowed[?]
+ #host = ''${concatMapStringsSep ", " toJSON (
+ # config.krebs.build.host.nets.retiolum.addrs
+ #)};
+ port = 6667;
+ sslport = 6697;
+ };
+
+ /* auth {}: allow users to connect to the ircd (OLD I:)
+ * auth {} blocks MUST be specified in order of precedence. The first one
+ * that matches a user will be used. So place spoofs first, then specials,
+ * then general access, then restricted.
+ */
+ auth {
+ /* user: the user@host allowed to connect. Multiple IPv4/IPv6 user
+ * lines are permitted per auth block. This is matched against the
+ * hostname and IP address (using :: shortening for IPv6 and
+ * prepending a 0 if it starts with a colon) and can also use CIDR
+ * masks.
+ */
+ user = "*@10.243.0.0/12";
+ user = "*@42::/16";
+
+ /* password: an optional password that is required to use this block.
+ * By default this is not encrypted, specify the flag "encrypted" in
+ * flags = ...; below if it is.
+ */
+ #password = "letmein";
+
+ /* spoof: fake the users user@host to be be this. You may either
+ * specify a host or a user@host to spoof to. This is free-form,
+ * just do everyone a favour and dont abuse it. (OLD I: = flag)
+ */
+ #spoof = "I.still.hate.packets";
+
+ /* Possible flags in auth:
+ *
+ * encrypted | password is encrypted with mkpasswd
+ * spoof_notice | give a notice when spoofing hosts
+ * exceed_limit (old > flag) | allow user to exceed class user limits
+ * kline_exempt (old ^ flag) | exempt this user from k/g/xlines&dnsbls
+ * dnsbl_exempt | exempt this user from dnsbls
+ * spambot_exempt | exempt this user from spambot checks
+ * shide_exempt | exempt this user from serverhiding
+ * jupe_exempt | exempt this user from generating
+ * warnings joining juped channels
+ * resv_exempt | exempt this user from resvs
+ * flood_exempt | exempt this user from flood limits
+ * USE WITH CAUTION.
+ * no_tilde (old - flag) | don't prefix ~ to username if no ident
+ * need_ident (old + flag) | require ident for user in this class
+ * need_ssl | require SSL/TLS for user in this class
+ * need_sasl | require SASL id for user in this class
+ */
+ flags = kline_exempt, exceed_limit, flood_exempt;
+
+ /* class: the class the user is placed in */
+ class = "krebs";
+ };
+
+ auth {
+ user = "*@*";
+ class = "users";
+ };
+
+ /* privset {} blocks MUST be specified before anything that uses them. That
+ * means they must be defined before operator {}.
+ */
+ privset "local_op" {
+ privs = oper:local_kill, oper:operwall;
+ };
+
+ privset "server_bot" {
+ extends = "local_op";
+ privs = oper:kline, oper:remoteban, snomask:nick_changes;
+ };
+
+ privset "global_op" {
+ extends = "local_op";
+ privs = oper:global_kill, oper:routing, oper:kline, oper:unkline, oper:xline,
+ oper:resv, oper:mass_notice, oper:remoteban;
+ };
+
+ privset "admin" {
+ extends = "global_op";
+ privs = oper:admin, oper:die, oper:rehash, oper:spy, oper:override;
+ };
+
+ privset "aids" {
+ privs = oper:override, oper:rehash;
+ };
+
+ operator "aids" {
+ user = "*@10.243.*";
+ privset = "aids";
+ flags = ~encrypted;
+ password = "balls";
+ };
+
+ operator "god" {
+ /* name: the name of the oper must go above */
+
+ /* user: the user@host required for this operator. CIDR *is*
+ * supported now. auth{} spoofs work here, other spoofs do not.
+ * multiple user="" lines are supported.
+ */
+ user = "*god@127.0.0.1";
+
+ /* password: the password required to oper. Unless ~encrypted is
+ * contained in flags = ...; this will need to be encrypted using
+ * mkpasswd, MD5 is supported
+ */
+ password = "5";
+
+ /* rsa key: the public key for this oper when using Challenge.
+ * A password should not be defined when this is used, see
+ * doc/challenge.txt for more information.
+ */
+ #rsa_public_key_file = "/usr/local/ircd/etc/oper.pub";
+
+ /* umodes: the specific umodes this oper gets when they oper.
+ * If this is specified an oper will not be given oper_umodes
+ * These are described above oper_only_umodes in general {};
+ */
+ #umodes = locops, servnotice, operwall, wallop;
+
+ /* fingerprint: if specified, the oper's client certificate
+ * fingerprint will be checked against the specified fingerprint
+ * below.
+ */
+ #fingerprint = "c77106576abf7f9f90cca0f63874a60f2e40a64b";
+
+ /* snomask: specific server notice mask on oper up.
+ * If this is specified an oper will not be given oper_snomask.
+ */
+ snomask = "+Zbfkrsuy";
+
+ /* flags: misc options for the operator. You may prefix an option
+ * with ~ to disable it, e.g. ~encrypted.
+ *
+ * Default flags are encrypted.
+ *
+ * Available options:
+ *
+ * encrypted: the password above is encrypted [DEFAULT]
+ * need_ssl: must be using SSL/TLS to oper up
+ */
+ flags = encrypted;
+
+ /* privset: privileges set to grant */
+ privset = "admin";
+ };
+
+ service {
+ name = "services.int";
+ };
+
+ cluster {
+ name = "*";
+ flags = kline, tkline, unkline, xline, txline, unxline, resv, tresv, unresv;
+ };
+
+ shared {
+ oper = "*@*", "*";
+ flags = all, rehash;
+ };
+
+ /* exempt {}: IPs that are exempt from Dlines and rejectcache. (OLD d:) */
+ exempt {
+ ip = "127.0.0.1";
+ };
+
+ channel {
+ use_invex = yes;
+ use_except = yes;
+ use_forward = yes;
+ use_knock = yes;
+ knock_delay = 5 minutes;
+ knock_delay_channel = 1 minute;
+ max_chans_per_user = 15;
+ max_bans = 100;
+ max_bans_large = 500;
+ default_split_user_count = 0;
+ default_split_server_count = 0;
+ no_create_on_split = no;
+ no_join_on_split = no;
+ burst_topicwho = yes;
+ kick_on_split_riding = no;
+ only_ascii_channels = no;
+ resv_forcepart = yes;
+ channel_target_change = yes;
+ disable_local_channels = no;
+ };
+
+ serverhide {
+ flatten_links = yes;
+ links_delay = 5 minutes;
+ hidden = no;
+ disable_hidden = no;
+ };
+
+ /* These are the blacklist settings.
+ * You can have multiple combinations of host and rejection reasons.
+ * They are used in pairs of one host/rejection reason.
+ *
+ * These settings should be adequate for most networks, and are (presently)
+ * required for use on StaticBox.
+ *
+ * Word to the wise: Do not use blacklists like SPEWS for blocking IRC
+ * connections.
+ *
+ * As of charybdis 2.2, you can do some keyword substitution on the rejection
+ * reason. The available keyword substitutions are:
+ *
+ * ''${ip} - the user's IP
+ * ''${host} - the user's canonical hostname
+ * ''${dnsbl-host} - the dnsbl hostname the lookup was done against
+ * ''${nick} - the user's nickname
+ * ''${network-name} - the name of the network
+ *
+ * As of charybdis 3.4, a type parameter is supported, which specifies the
+ * address families the blacklist supports. IPv4 and IPv6 are supported.
+ * IPv4 is currently the default as few blacklists support IPv6 operation
+ * as of this writing.
+ *
+ * Note: AHBL (the providers of the below *.ahbl.org BLs) request that they be
+ * contacted, via email, at admins@2mbit.com before using these BLs.
+ * See <http://www.ahbl.org/services.php> for more information.
+ */
+ blacklist {
+ host = "rbl.efnetrbl.org";
+ type = ipv4;
+ reject_reason = "''${nick}, your IP (''${ip}) is listed in EFnet's RBL. For assistance, see http://efnetrbl.org/?i=''${ip}";
+
+ # host = "ircbl.ahbl.org";
+ # type = ipv4;
+ # reject_reason = "''${nick}, your IP (''${ip}) is listed in ''${dnsbl-host} for having an open proxy. In order to protect ''${network-name} from abuse, we are not allowing connections with open proxies to connect.";
+ #
+ # host = "tor.ahbl.org";
+ # type = ipv4;
+ # reject_reason = "''${nick}, your IP (''${ip}) is listed as a TOR exit node. In order to protect ''${network-name} from tor-based abuse, we are not allowing TOR exit nodes to connect to our network.";
+ #
+ /* Example of a blacklist that supports both IPv4 and IPv6 */
+ # host = "foobl.blacklist.invalid";
+ # type = ipv4, ipv6;
+ # reject_reason = "''${nick}, your IP (''${ip}) is listed in ''${dnsbl-host} for some reason. In order to protect ''${network-name} from abuse, we are not allowing connections listed in ''${dnsbl-host} to connect";
+ };
+
+ alias "NickServ" {
+ target = "NickServ";
+ };
+
+ alias "ChanServ" {
+ target = "ChanServ";
+ };
+
+ alias "OperServ" {
+ target = "OperServ";
+ };
+
+ alias "MemoServ" {
+ target = "MemoServ";
+ };
+
+ alias "NS" {
+ target = "NickServ";
+ };
+
+ alias "CS" {
+ target = "ChanServ";
+ };
+
+ alias "OS" {
+ target = "OperServ";
+ };
+
+ alias "MS" {
+ target = "MemoServ";
+ };
+
+ general {
+ hide_error_messages = opers;
+ hide_spoof_ips = yes;
+
+ /*
+ * default_umodes: umodes to enable on connect.
+ * If you have enabled the new ip_cloaking_4.0 module, and you want
+ * to make use of it, add +x to this option, i.e.:
+ * default_umodes = "+ix";
+ *
+ * If you have enabled the old ip_cloaking module, and you want
+ * to make use of it, add +h to this option, i.e.:
+ * default_umodes = "+ih";
+ */
+ default_umodes = "+i";
+
+ default_operstring = "is an IRC Operator";
+ default_adminstring = "is a Server Administrator";
+ servicestring = "is a Network Service";
+ disable_fake_channels = no;
+ tkline_expire_notices = no;
+ default_floodcount = 1000;
+ failed_oper_notice = yes;
+ dots_in_ident=2;
+ min_nonwildcard = 4;
+ min_nonwildcard_simple = 3;
+ max_accept = 100;
+ max_monitor = 100;
+ anti_nick_flood = yes;
+ max_nick_time = 20 seconds;
+ max_nick_changes = 5;
+ anti_spam_exit_message_time = 5 minutes;
+ ts_warn_delta = 30 seconds;
+ ts_max_delta = 5 minutes;
+ client_exit = yes;
+ collision_fnc = yes;
+ resv_fnc = yes;
+ global_snotices = yes;
+ dline_with_reason = yes;
+ kline_delay = 0 seconds;
+ kline_with_reason = yes;
+ kline_reason = "K-Lined";
+ identify_service = "NickServ@services.int";
+ identify_command = "IDENTIFY";
+ non_redundant_klines = yes;
+ warn_no_nline = yes;
+ use_propagated_bans = yes;
+ stats_e_disabled = no;
+ stats_c_oper_only=no;
+ stats_h_oper_only=no;
+ client_flood_max_lines = 16000;
+ client_flood_burst_rate = 32000;
+ client_flood_burst_max = 32000;
+ client_flood_message_num = 32000;
+ client_flood_message_time = 32000;
+ use_whois_actually = no;
+ oper_only_umodes = operwall, locops, servnotice;
+ oper_umodes = locops, servnotice, operwall, wallop;
+ oper_snomask = "+s";
+ burst_away = yes;
+ nick_delay = 0 seconds; # 15 minutes if you want to enable this
+ reject_ban_time = 1 minute;
+ reject_after_count = 3;
+ reject_duration = 5 minutes;
+ throttle_duration = 60;
+ throttle_count = 4;
+ max_ratelimit_tokens = 30;
+ away_interval = 30;
+ };
+
+ modules {
+ path = "modules";
+ path = "modules/autoload";
+ };
+
+ exempt {
+ ip = "10.243.0.0/16";
+ };
+ '';
+in
+out
diff --git a/tv/2configs/consul-client.nix b/tv/2configs/consul-client.nix
new file mode 100644
index 000000000..0a8bf4d75
--- /dev/null
+++ b/tv/2configs/consul-client.nix
@@ -0,0 +1,9 @@
+{ pkgs, ... }:
+
+{
+ imports = [ ./consul-server.nix ];
+
+ tv.consul = {
+ server = pkgs.lib.mkForce false;
+ };
+}
diff --git a/tv/2configs/consul-server.nix b/tv/2configs/consul-server.nix
new file mode 100644
index 000000000..d10f9ea75
--- /dev/null
+++ b/tv/2configs/consul-server.nix
@@ -0,0 +1,21 @@
+{ config, ... }:
+
+{
+ tv.consul = rec {
+ enable = true;
+
+ self = config.krebs.build.host;
+ inherit (self) dc;
+
+ server = true;
+
+ hosts = with config.krebs.hosts; [
+ # TODO get this list automatically from each host where tv.consul.enable is true
+ cd
+ mkdir
+ nomic
+ rmdir
+ #wu
+ ];
+ };
+}
diff --git a/tv/2configs/cryptoroot.nix b/tv/2configs/cryptoroot.nix
new file mode 100644
index 000000000..04618ac4a
--- /dev/null
+++ b/tv/2configs/cryptoroot.nix
@@ -0,0 +1,4 @@
+{ ... }:
+
+{
+}
diff --git a/tv/2configs/exim-retiolum.nix b/tv/2configs/exim-retiolum.nix
new file mode 100644
index 000000000..851a0c625
--- /dev/null
+++ b/tv/2configs/exim-retiolum.nix
@@ -0,0 +1,126 @@
+{ config, pkgs, ... }:
+
+{
+ services.exim =
+ # This configuration makes only sense for retiolum-enabled hosts.
+ # TODO modular configuration
+ assert config.krebs.retiolum.enable;
+ let
+ # TODO get the hostname from config.krebs.retiolum.
+ retiolumHostname = "${config.networking.hostName}.retiolum";
+ in
+ { enable = true;
+ config = ''
+ primary_hostname = ${retiolumHostname}
+ domainlist local_domains = @ : localhost
+ domainlist relay_to_domains = *.retiolum
+ hostlist relay_from_hosts = <; 127.0.0.1 ; ::1
+
+ acl_smtp_rcpt = acl_check_rcpt
+ acl_smtp_data = acl_check_data
+
+ host_lookup = *
+ rfc1413_hosts = *
+ rfc1413_query_timeout = 5s
+
+ log_file_path = syslog
+ syslog_timestamp = false
+ syslog_duplication = false
+
+ begin acl
+
+ acl_check_rcpt:
+ accept hosts = :
+ control = dkim_disable_verify
+
+ deny message = Restricted characters in address
+ domains = +local_domains
+ local_parts = ^[.] : ^.*[@%!/|]
+
+ deny message = Restricted characters in address
+ domains = !+local_domains
+ local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
+
+ accept local_parts = postmaster
+ domains = +local_domains
+
+ #accept
+ # hosts = *.retiolum
+ # domains = *.retiolum
+ # control = dkim_disable_verify
+
+ #require verify = sender
+
+ accept hosts = +relay_from_hosts
+ control = submission
+ control = dkim_disable_verify
+
+ accept authenticated = *
+ control = submission
+ control = dkim_disable_verify
+
+ require message = relay not permitted
+ domains = +local_domains : +relay_to_domains
+
+ require verify = recipient
+
+ accept
+
+
+ acl_check_data:
+ accept
+
+
+ begin routers
+
+ retiolum:
+ driver = manualroute
+ domains = ! ${retiolumHostname} : *.retiolum
+ transport = remote_smtp
+ route_list = ^.* $0 byname
+ no_more
+
+ nonlocal:
+ debug_print = "R: nonlocal for $local_part@$domain"
+ driver = redirect
+ domains = ! +local_domains
+ allow_fail
+ data = :fail: Mailing to remote domains not supported
+ no_more
+
+ local_user:
+ # debug_print = "R: local_user for $local_part@$domain"
+ driver = accept
+ check_local_user
+ # local_part_suffix = +* : -*
+ # local_part_suffix_optional
+ transport = home_maildir
+ cannot_route_message = Unknown user
+
+
+ begin transports
+
+ remote_smtp:
+ driver = smtp
+
+ home_maildir:
+ driver = appendfile
+ maildir_format
+ directory = $home/Maildir
+ directory_mode = 0700
+ delivery_date_add
+ envelope_to_add
+ return_path_add
+ # group = mail
+ # mode = 0660
+
+ begin retry
+ *.retiolum * F,42d,1m
+ * * F,2h,15m; G,16h,1h,1.5; F,4d,6h
+
+ begin rewrite
+
+ begin authenticators
+ '';
+ };
+}
diff --git a/tv/2configs/exim-smarthost.nix b/tv/2configs/exim-smarthost.nix
new file mode 100644
index 000000000..c93189b8a
--- /dev/null
+++ b/tv/2configs/exim-smarthost.nix
@@ -0,0 +1,475 @@
+{ config, pkgs, ... }:
+
+let
+ inherit (builtins) toFile;
+ inherit (pkgs.lib.attrsets) mapAttrs;
+ inherit (pkgs.lib.strings) concatMapStringsSep;
+in
+
+{
+ services.exim =
+ let
+ retiolumHostname = "${config.networking.hostName}.retiolum";
+
+ internet-aliases = with config.krebs.users; [
+ { from = "tomislav@viljetic.de"; to = tv.mail; }
+
+ # (mindestens) lisp-stammtisch und elli haben die:
+ { from = "tv@viljetic.de"; to = tv.mail; }
+
+ { from = "tv@destroy.dyn.shackspace.de"; to = tv.mail; }
+
+ { from = "mirko@viljetic.de"; to = mv.mail; }
+
+ # TODO killme (wo wird die benutzt?)
+ { from = "tv@cd.retiolum"; to = tv.mail; }
+
+ # TODO lists@smtp.retiolum [consul]
+ { from = "postmaster@krebsco.de"; to = tv.mail; }
+ ];
+
+ system-aliases = [
+ { from = "mailer-daemon"; to = "postmaster"; }
+ { from = "postmaster"; to = "root"; }
+ { from = "nobody"; to = "root"; }
+ { from = "hostmaster"; to = "root"; }
+ { from = "usenet"; to = "root"; }
+ { from = "news"; to = "root"; }
+ { from = "webmaster"; to = "root"; }
+ { from = "www"; to = "root"; }
+ { from = "ftp"; to = "root"; }
+ { from = "abuse"; to = "root"; }
+ { from = "noc"; to = "root"; }
+ { from = "security"; to = "root"; }
+ { from = "root"; to = "tv"; }
+ { from = "mirko"; to = "mv"; }
+ ];
+
+ to-lsearch = concatMapStringsSep "\n" ({ from, to }: "${from}: ${to}");
+ lsearch =
+ mapAttrs (name: set: toFile name (to-lsearch set)) {
+ inherit internet-aliases;
+ inherit system-aliases;
+ };
+ in
+ {
+ enable = true;
+ config =
+ ''
+ primary_hostname = ${retiolumHostname}
+
+ # HOST_REDIR contains the real destinations for "local_domains".
+ #HOST_REDIR = /etc/exim4/host_redirect
+
+
+ # Domains not listed in local_domains need to be deliverable remotely.
+ # XXX We abuse local_domains to mean "domains, we're the gateway for".
+ domainlist local_domains = @ : localhost
+ #: viljetic.de : SHACK_REDIR_HOSTNAME
+ domainlist relay_to_domains =
+ hostlist relay_from_hosts = <; 127.0.0.1 ; ::1 ; 10.243.13.37
+
+ acl_smtp_rcpt = acl_check_rcpt
+ acl_smtp_data = acl_check_data
+
+ # av_scanner = clamd:/tmp/clamd
+ # spamd_address = 127.0.0.1 783
+
+ # tls_advertise_hosts = *
+ # tls_certificate = /etc/ssl/exim.crt
+ # tls_privatekey = /etc/ssl/exim.pem
+ # (debian) tls_verify_certificates (to check client certs)
+
+ # daemon_smtp_ports = 25 : 465 : 587
+ # tls_on_connect_ports = 465
+
+ # qualify_domain defaults to primary_hostname
+ # qualify_recipient defaults to qualify_domain
+
+ # allow_domain_literals
+
+ never_users = root
+
+ host_lookup = *
+
+ # ident callbacks for all incoming SMTP calls
+ rfc1413_hosts = *
+ rfc1413_query_timeout = 5s
+
+ # sender_unqualified_hosts =
+ # recipient_unqualified_hosts =
+
+ # percent_hack_domains =
+
+ # arch & debian
+ #ignore_bounce_errors_after = 2d
+ #timeout_frozen_after = 7d
+ # debian
+ #smtp_banner = $smtp_active_hostname ESMTP Exim $version_number $tod_full
+ #freeze_tell = postmaster
+ #trusted_users = uucp
+ # arch
+ #split_spool_directory = true
+
+ log_selector = -queue_run +address_rewrite +all_parents +queue_time
+ log_file_path = syslog
+ syslog_timestamp = false
+ syslog_duplication = false
+
+ begin acl
+
+ acl_check_rcpt:
+ # Accept if the source is local SMTP (i.e. not over TCP/IP).
+ # We do this by testing for an empty sending host field.
+ accept hosts = :
+ # arch & debian:
+ control = dkim_disable_verify
+
+ deny message = Restricted characters in address
+ domains = +local_domains
+ local_parts = ^[.] : ^.*[@%!/|]
+
+ deny message = Restricted characters in address
+ domains = !+local_domains
+ local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
+
+ accept local_parts = postmaster
+ domains = +local_domains
+
+ ## feature RETIOLUM_MAIL
+ #accept
+ # hosts = *.retiolum
+ # domains = *.retiolum
+ # control = dkim_disable_verify
+
+ #require verify = sender
+
+ accept hosts = +relay_from_hosts
+ control = submission
+ # debian: control = submission/sender_retain
+ # arch & debian:
+ control = dkim_disable_verify
+
+ accept authenticated = *
+ control = submission
+ control = dkim_disable_verify
+
+ accept message = relay not permitted 2
+ recipients = lsearch;${lsearch.internet-aliases}
+
+ require message = relay not permitted
+ domains = +local_domains : +relay_to_domains
+
+ require
+ message = unknown user
+ verify = recipient/callout
+
+ # deny message = rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
+ # dnslists = black.list.example
+ #
+ # warn dnslists = black.list.example
+ # add_header = X-Warning: $sender_host_address is in a black list at $dnslist_domain
+ # log_message = found in $dnslist_domain
+
+ # Client SMTP Authorization (csa) checks on the sending host.
+ # Such checks do DNS lookups for special SRV records.
+ # require verify = csa
+
+ accept
+
+
+ acl_check_data:
+ # see av_scanner
+ #deny malware = *
+ # message = This message contains a virus ($malware_name).
+
+ # Add headers to a message if it is judged to be spam. Before enabling this,
+ # you must install SpamAssassin. You may also need to set the spamd_address
+ # option above.
+ #
+ # warn spam = nobody
+ # add_header = X-Spam_score: $spam_score\n\
+ # X-Spam_score_int: $spam_score_int\n\
+ # X-Spam_bar: $spam_bar\n\
+ # X-Spam_report: $spam_report
+
+ # feature HELO_REWRITE
+ # XXX note that the public ip (162.219.5.183) resolves to viljetic.de
+ warn
+ sender_domains = viljetic.de : shackspace.de
+ set acl_m_special_dom = $sender_address_domain
+
+ accept
+
+
+ begin routers
+
+ # feature RETIOLUM_MAIL
+ retiolum:
+ debug_print = "R: retiolum for $local_part@$domain"
+ driver = manualroute
+ domains = ! ${retiolumHostname} : *.retiolum
+ transport = retiolum_smtp
+ route_list = ^.* $0 byname
+ no_more
+
+ internet_aliases:
+ debug_print = "R: internet_aliases for $local_part@$domain"
+ driver = redirect
+ data = ''${lookup{$local_part@$domain}lsearch{${lsearch.internet-aliases}}}
+
+ dnslookup:
+ debug_print = "R: dnslookup for $local_part@$domain"
+ driver = dnslookup
+ domains = ! +local_domains
+ transport = remote_smtp
+ ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
+ # if ipv6-enabled then instead use:
+ # ignore_target_hosts = <; 0.0.0.0 ; 127.0.0.0/8 ; ::1
+
+ # (debian) same_domain_copy_routing = yes
+ # (debian) ignore private rfc1918 and APIPA addresses
+ # (debian) ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 : 192.168.0.0/16 :\
+ # 172.16.0.0/12 : 10.0.0.0/8 : 169.254.0.0/16 :\
+ # 255.255.255.255
+
+ # Fail and bounce if the router does not find the domain in the DNS.
+ # I.e. no more routers are tried.
+ # There are a few cases where a dnslookup router will decline to accept an
+ # address; if such a router is expected to handle "all remaining non-local
+ # domains", then it is important to set no_more.
+ no_more
+
+ # XXX this is only used because these "well known aliases" goto tv@cd.retiolum
+ # TODO bounce everything, there is no @cd.retiolum
+ system_aliases:
+ debug_print = "R: system_aliases for $local_part@$domain"
+ driver = redirect
+ data = ''${lookup{$local_part}lsearch{${lsearch.system-aliases}}}
+
+ # TODO this is only b/c mv here... send mv's mails somewhere else...
+ local_user:
+ debug_print = "R: local_user for $local_part@$domain"
+ driver = accept
+ check_local_user
+ # local_part_suffix = +* : -*
+ # local_part_suffix_optional
+ transport = home_maildir
+ cannot_route_message = Unknown user
+
+ begin transports
+
+ retiolum_smtp:
+ driver = smtp
+ retry_include_ip_address = false
+ # serialize_hosts = TODO-all-slow-hosts
+
+ remote_smtp:
+ driver = smtp
+ # debian has also stuff for tls, headers_rewrite and more here
+
+ # feature HELO_REWRITE
+ # XXX note that the public ip (162.219.5.183) resolves to viljetic.de
+ helo_data = ''${if eq{$acl_m_special_dom}{} \
+ {$primary_hostname} \
+ {$acl_m_special_dom} }
+
+ home_maildir:
+ driver = appendfile
+ maildir_format
+ maildir_use_size_file
+ directory = $home/Mail
+ directory_mode = 0700
+ delivery_date_add
+ envelope_to_add
+ return_path_add
+
+ begin retry
+ *.retiolum * F,42d,1m
+ * * F,2h,15m; G,16h,1h,1.5; F,4d,6h
+
+ begin rewrite
+ begin authenticators
+ '';
+
+
+ # group = mail
+ # mode = 0660
+
+
+ #address_pipe:
+ # driver = pipe
+ # return_output
+ #
+ #address_file:
+ # driver = appendfile
+ # delivery_date_add
+ # envelope_to_add
+ # return_path_add
+ #
+ #address_reply:
+ # driver = autoreply
+
+
+ #maildrop_pipe:
+ # debug_print = "T: maildrop_pipe for $local_part@$domain"
+ # driver = pipe
+ # path = "/bin:/usr/bin:/usr/local/bin"
+ # command = "/usr/bin/maildrop"
+ # return_path_add
+ # delivery_date_add
+ # envelope_to_add
+
+
+
+
+
+ ##begin retry
+ # Address or Domain Error Retries
+
+ # Our host_redirect destinations might be offline a lot.
+ # TODO define fallback destinations(?)
+ #lsearch;${lsearch.internet-aliases} * F,42d,1m
+
+
+ ## begin rewrite
+
+ # just in case (shackspace.de should already do this)
+ #tv@shackspace.de tv@SHACK_REDIR_HOSTNAME T
+
+
+ ## begin authenticators
+ #PLAIN:
+ # driver = plaintext
+ # server_set_id = $auth2
+ # server_prompts = :
+ # server_condition = Authentication is not yet configured
+ # server_advertise_condition = ''${if def:tls_in_cipher }
+
+ #LOGIN:
+ # driver = plaintext
+ # server_set_id = $auth1
+ # server_prompts = <| Username: | Password:
+ # server_condition = Authentication is not yet configured
+ # server_advertise_condition = ''${if def:tls_in_cipher }
+
+
+
+ };
+
+}
+
+# config = ''
+# primary_hostname = ${retiolumHostname}
+# domainlist local_domains = @ : localhost
+# domainlist relay_to_domains = *.retiolum
+# hostlist relay_from_hosts = <; 127.0.0.1 ; ::1
+#
+# acl_smtp_rcpt = acl_check_rcpt
+# acl_smtp_data = acl_check_data
+#
+# host_lookup = *
+# rfc1413_hosts = *
+# rfc1413_query_timeout = 5s
+#
+# log_file_path = syslog
+# syslog_timestamp = false
+# syslog_duplication = false
+#
+# begin acl
+#
+# acl_check_rcpt:
+# accept hosts = :
+# control = dkim_disable_verify
+#
+# deny message = Restricted characters in address
+# domains = +local_domains
+# local_parts = ^[.] : ^.*[@%!/|]
+#
+# deny message = Restricted characters in address
+# domains = !+local_domains
+# local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
+#
+# accept local_parts = postmaster
+# domains = +local_domains
+#
+# #accept
+# # hosts = *.retiolum
+# # domains = *.retiolum
+# # control = dkim_disable_verify
+#
+# #require verify = sender
+#
+# accept hosts = +relay_from_hosts
+# control = submission
+# control = dkim_disable_verify
+#
+# accept authenticated = *
+# control = submission
+# control = dkim_disable_verify
+#
+# require message = relay not permitted
+# domains = +local_domains : +relay_to_domains
+#
+# require verify = recipient
+#
+# accept
+#
+#
+# acl_check_data:
+# accept
+#
+#
+# begin routers
+#
+# retiolum:
+# driver = manualroute
+# domains = ! ${retiolumHostname} : *.retiolum
+# transport = remote_smtp
+# route_list = ^.* $0 byname
+# no_more
+#
+# nonlocal:
+# debug_print = "R: nonlocal for $local_part@$domain"
+# driver = redirect
+# domains = ! +local_domains
+# allow_fail
+# data = :fail: Mailing to remote domains not supported
+# no_more
+#
+# local_user:
+# # debug_print = "R: local_user for $local_part@$domain"
+# driver = accept
+# check_local_user
+# # local_part_suffix = +* : -*
+# # local_part_suffix_optional
+# transport = home_maildir
+# cannot_route_message = Unknown user
+#
+#
+# begin transports
+#
+# remote_smtp:
+# driver = smtp
+#
+# home_maildir:
+# driver = appendfile
+# maildir_format
+# directory = $home/Maildir
+# directory_mode = 0700
+# delivery_date_add
+# envelope_to_add
+# return_path_add
+# # group = mail
+# # mode = 0660
+#
+# begin retry
+# *.retiolum * F,42d,1m
+# * * F,2h,15m; G,16h,1h,1.5; F,4d,6h
+#
+# begin rewrite
+#
+# begin authenticators
+# '';
+# };
+#}
diff --git a/tv/2configs/git.nix b/tv/2configs/git.nix
new file mode 100644
index 000000000..ecb98cef2
--- /dev/null
+++ b/tv/2configs/git.nix
@@ -0,0 +1,90 @@
+{ config, lib, pkgs, ... }:
+
+with import ../4lib { inherit lib pkgs; };
+let
+
+ out = {
+ krebs.git = {
+ enable = true;
+ root-title = "public repositories at ${config.krebs.build.host.name}";
+ root-desc = "keep calm and engage";
+ inherit repos rules;
+ };
+ };
+
+ repos = mapAttrs (_: s: removeAttrs s ["collaborators"]) (
+ public-repos //
+ optionalAttrs config.krebs.build.host.secure restricted-repos
+ );
+
+ rules = concatMap make-rules (attrValues repos);
+
+ public-repos = mapAttrs make-public-repo {
+ cgserver = {};
+ crude-mail-setup = {};
+ dot-xmonad = {};
+ hack = {};
+ load-env = {};
+ make-snapshot = {};
+ mime = {};
+ much = {};
+ nixos-infest = {};
+ nixpkgs = {};
+ painload = {};
+ quipper = {};
+ regfish = {};
+ stockholm = {
+ desc = "take all the computers hostage, they'll love you!";
+ };
+ wai-middleware-time = {};
+ web-routes-wai-custom = {};
+ xintmap = {};
+ };
+
+ restricted-repos = mapAttrs make-restricted-repo (
+ {
+ brain = {
+ collaborators = with config.krebs.users; [ lass makefu ];
+ };
+ } //
+ import /root/src/secrets/repos.nix { inherit config lib pkgs; }
+ );
+
+ make-public-repo = name: { desc ? null, ... }: {
+ inherit name desc;
+ public = true;
+ hooks = {
+ post-receive = git.irc-announce {
+ # TODO make nick = config.krebs.build.host.name the default
+ nick = config.krebs.build.host.name;
+ channel = "#retiolum";
+ server = "cd.retiolum";
+ };
+ };
+ };
+
+ make-restricted-repo = name: { desc ? null, ... }: {
+ inherit name desc;
+ public = false;
+ };
+
+ make-rules =
+ with git // config.krebs.users;
+ repo:
+ singleton {
+ user = tv;
+ repo = [ repo ];
+ perm = push "refs/*" [ non-fast-forward create delete merge ];
+ } ++
+ optional repo.public {
+ user = [ lass makefu uriel ];
+ repo = [ repo ];
+ perm = fetch;
+ } ++
+ optional (length (repo.collaborators or []) > 0) {
+ user = repo.collaborators;
+ repo = [ repo ];
+ perm = fetch;
+ };
+
+in out
diff --git a/tv/2configs/mail-client.nix b/tv/2configs/mail-client.nix
new file mode 100644
index 000000000..a632cf7c4
--- /dev/null
+++ b/tv/2configs/mail-client.nix
@@ -0,0 +1,14 @@
+{ pkgs, ... }:
+
+with import ../5pkgs { inherit pkgs; };
+
+{
+ environment.systemPackages = [
+ much
+ msmtp
+ notmuch
+ pythonPackages.alot
+ qprint
+ w3m
+ ];
+}
diff --git a/tv/2configs/smartd.nix b/tv/2configs/smartd.nix
new file mode 100644
index 000000000..9c4d8b2d8
--- /dev/null
+++ b/tv/2configs/smartd.nix
@@ -0,0 +1,17 @@
+{ config, pkgs, ... }:
+
+{
+ services.smartd = {
+ enable = true;
+ devices = [
+ {
+ device = "DEVICESCAN";
+ options = toString [
+ "-a"
+ "-m ${config.krebs.users.tv.mail}"
+ "-s (O/../.././09|S/../.././04|L/../../6/05)"
+ ];
+ }
+ ];
+ };
+}
diff --git a/tv/2configs/synaptics.nix b/tv/2configs/synaptics.nix
new file mode 100644
index 000000000..c47cb9deb
--- /dev/null
+++ b/tv/2configs/synaptics.nix
@@ -0,0 +1,14 @@
+{ config, pkgs, ... }:
+
+{
+ # TODO this is host specific
+ services.xserver.synaptics = {
+ enable = true;
+ twoFingerScroll = true;
+ accelFactor = "0.035";
+ additionalOptions = ''
+ Option "FingerHigh" "60"
+ Option "FingerLow" "60"
+ '';
+ };
+}
diff --git a/tv/2configs/urlwatch.nix b/tv/2configs/urlwatch.nix
new file mode 100644
index 000000000..a69b1519c
--- /dev/null
+++ b/tv/2configs/urlwatch.nix
@@ -0,0 +1,51 @@
+{ config, ... }:
+
+{
+ krebs.urlwatch = {
+ enable = true;
+ mailto = config.krebs.users.tv.mail;
+ onCalendar = "*-*-* 05:00:00";
+ urls = [
+ ## nixpkgs maintenance
+
+ # 2014-07-29 when one of the following urls change
+ # then we have to update the package
+
+ # ref src/nixpkgs/pkgs/tools/admin/sec/default.nix
+ https://api.github.com/repos/simple-evcorr/sec/tags
+
+ # ref src/nixpkgs/pkgs/tools/networking/urlwatch/default.nix
+ https://thp.io/2008/urlwatch/
+
+ # 2014-12-20 ref src/nixpkgs/pkgs/tools/networking/tlsdate/default.nix
+ https://api.github.com/repos/ioerror/tlsdate/tags
+
+ # 2015-02-18
+ # ref ~/src/nixpkgs/pkgs/tools/text/qprint/default.nix
+ http://www.fourmilab.ch/webtools/qprint/
+
+ # 2014-09-24 ref https://github.com/4z3/xintmap
+ http://www.mathstat.dal.ca/~selinger/quipper/
+
+ # 2014-12-12 remove nixopsUnstable when nixops get's bumped to 1.3
+ # ref https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/package-management/nixops/unstable.nix
+ http://nixos.org/releases/nixops/
+
+ ## other
+
+ https://nixos.org/channels/nixos-unstable/git-revision
+
+ ## 2014-10-17
+ ## TODO update ~/src/login/default.nix
+ #http://hackage.haskell.org/package/bcrypt
+ #http://hackage.haskell.org/package/cron
+ #http://hackage.haskell.org/package/hyphenation
+ #http://hackage.haskell.org/package/iso8601-time
+ #http://hackage.haskell.org/package/ixset-typed
+ #http://hackage.haskell.org/package/system-command
+ #http://hackage.haskell.org/package/transformers
+ #http://hackage.haskell.org/package/web-routes-wai
+ #http://hackage.haskell.org/package/web-page
+ ];
+ };
+}
diff --git a/tv/2configs/urxvt.nix b/tv/2configs/urxvt.nix
new file mode 100644
index 000000000..89bb421aa
--- /dev/null
+++ b/tv/2configs/urxvt.nix
@@ -0,0 +1,24 @@
+{ pkgs, ... }:
+
+with builtins;
+
+let
+ users = [ "tv" ];
+ urxvt = pkgs.rxvt_unicode;
+ mkService = user: {
+ description = "urxvt terminal daemon";
+ wantedBy = [ "multi-user.target" ];
+ restartIfChanged = false;
+ serviceConfig = {
+ Restart = "always";
+ User = user;
+ ExecStart = "${urxvt}/bin/urxvtd";
+ };
+ };
+
+in
+
+{
+ environment.systemPackages = [ urxvt ];
+ systemd.services = listToAttrs (map (u: { name = "${u}-urxvtd"; value = mkService u; }) users);
+}
diff --git a/tv/2configs/w110er.nix b/tv/2configs/w110er.nix
new file mode 100644
index 000000000..e580b2161
--- /dev/null
+++ b/tv/2configs/w110er.nix
@@ -0,0 +1,42 @@
+{ pkgs, ... }:
+
+{
+ imports = [
+ ../2configs/smartd.nix
+ ];
+
+ boot.extraModprobeConfig = ''
+ options kvm_intel nested=1
+ '';
+
+ boot.initrd.availableKernelModules = [ "ahci" ];
+ boot.kernelModules = [ "kvm-intel" ];
+
+ boot.loader.gummiboot.enable = true;
+ boot.loader.efi.canTouchEfiVariables = true;
+
+ networking.wireless.enable = true;
+
+ nix = {
+ buildCores = 4;
+ maxJobs = 4;
+ daemonIONiceLevel = 1;
+ daemonNiceLevel = 1;
+ };
+
+ services.logind.extraConfig = ''
+ HandleHibernateKey=ignore
+ HandleLidSwitch=ignore
+ HandlePowerKey=ignore
+ HandleSuspendKey=ignore
+ '';
+
+ system.activationScripts.powertopTunables = ''
+ echo 1 > /sys/module/snd_hda_intel/parameters/power_save
+ echo 1500 > /proc/sys/vm/dirty_writeback_centisecs
+ (cd /sys/bus/pci/devices
+ for i in *; do
+ echo auto > $i/power/control # defaults to 'on'
+ done)
+ '';
+}
diff --git a/tv/2configs/xserver.nix b/tv/2configs/xserver.nix
new file mode 100644
index 000000000..7fc07f927
--- /dev/null
+++ b/tv/2configs/xserver.nix
@@ -0,0 +1,41 @@
+{ config, pkgs, ... }:
+
+{
+ imports = [
+ ../2configs/urxvt.nix # TODO via xserver
+ ];
+
+ services.xserver.enable = true;
+
+
+ #fonts.enableFontConfig = true;
+ #fonts.enableFontDir = true;
+ fonts.fonts = [
+ pkgs.xlibs.fontschumachermisc
+ ];
+ #services.xfs.enable = true;
+ #services.xserver.useXFS = "unix/:7100";
+
+ services.xserver.displayManager.desktopManagerHandlesLidAndPower = true;
+
+ #services.xserver.display = 11;
+ #services.xserver.tty = 11;
+ # services.xserver.layout = "us";
+ # services.xserver.xkbOptions = "eurosign:e";
+
+ #services.xserver.multitouch.enable = true;
+
+ services.xserver.windowManager.xmonad.extraPackages = hspkgs: with hspkgs; [
+ X11-xshape
+ ];
+ services.xserver.windowManager.xmonad.enable = true;
+ services.xserver.windowManager.xmonad.enableContribAndExtras = true;
+ services.xserver.windowManager.default = "xmonad";
+ services.xserver.desktopManager.default = "none";
+ services.xserver.desktopManager.xterm.enable = false;
+
+ services.xserver.displayManager.slim.enable = true;
+ #services.xserver.displayManager.auto.enable = true;
+ #services.xserver.displayManager.auto.user = "tv";
+ #services.xserver.displayManager.job.logsXsession = true;
+}
[cgit] Unable to lock slot /tmp/cgit/92100000.lock: No such file or directory (2)