├── .gitignore
├── LICENSE
├── README.md
├── server
├── base.nix
├── configuration.nix
├── container
│ └── nextcloud.nix
├── pkg
│ ├── jank-benchmark.nix
│ ├── safepaste.nix
│ └── wordy-word.nix
├── program
│ ├── admin.nix
│ └── essential.nix
├── service
│ ├── acme.nix
│ ├── data
│ │ ├── park-index.html
│ │ └── upgrade-rainloop
│ ├── domain-parking.nix
│ ├── dovecot.nix
│ ├── fail2ban.nix
│ ├── gpg.nix
│ ├── httpd.nix
│ ├── jank-benchmark.nix
│ ├── jank-license.nix
│ ├── opendkim.nix
│ ├── postfix.nix
│ ├── radicale.nix
│ ├── rainloop.nix
│ ├── safepaste.nix
│ ├── spamassassin.nix
│ ├── taskserver.nix
│ ├── upload.jeaye.com-tmp.nix
│ └── wordy-word.nix
├── system
│ ├── environment.nix
│ ├── network.nix
│ ├── security.nix
│ └── user.nix
├── user
│ ├── fu-er.nix
│ ├── git.nix
│ ├── irc.nix
│ ├── jeaye.nix
│ └── okletsplay.nix
└── util
│ ├── acme.nix
│ └── http.nix
├── shared
├── configuration.nix
├── service
│ ├── locate.nix
│ ├── ssh.nix
│ └── time.nix
└── system
│ ├── boot.nix
│ ├── environment.nix
│ ├── network.nix
│ ├── security.nix
│ ├── systemd.nix
│ └── user.nix
└── workstation
├── configuration.nix
├── hardware-configuration.nix
├── program
└── essential.nix
├── service
├── docker.nix
├── ssh.nix
├── virtualbox.nix
└── x11.nix
├── system
├── boot.nix
├── environment.nix
├── network.nix
├── network
│ └── malicious-host.nix
├── security.nix
├── sound.nix
├── usb.nix
└── user.nix
└── user
├── jeaye.nix
└── jeaye
├── data
└── dotfiles
│ ├── Xresources
│ ├── bash_profile
│ ├── bashrc
│ ├── bashrc-alias
│ ├── bashrc-less
│ ├── bashrc-prompt
│ ├── bin
│ ├── define
│ ├── i3data
│ ├── lock
│ ├── super-nice
│ ├── upload
│ └── youtube-dl-audio
│ ├── config
│ └── i3
│ │ └── config
│ ├── gitconfig
│ ├── gitignore
│ ├── i3status.conf
│ ├── lein
│ └── profiles.clj
│ ├── mpv
│ └── mpv.conf
│ ├── tmux.conf
│ └── xinitrc
├── desktop.nix
├── gaming.nix
├── home.nix
├── pkg
└── vimrc.nix
└── program.nix
/.gitignore:
--------------------------------------------------------------------------------
1 | /hardware-configuration.nix
2 | /configuration.nix
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright © 2017 Jesse 'Jeaye' Wilkerson. All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted, free of charge, provided that the following
5 | conditions are met:
6 |
7 | Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | Redistributions in any form must be accompanied by information on how to obtain
15 | complete source code for the distributed software and any accompanying software
16 | that uses the distributed software. The source code must either be included in
17 | the distribution or be available free of charge. For an executable file,
18 | complete source code means the source code for all modules it contains. It does
19 | not include source code for modules or files that typically accompany the major
20 | components of the operating system on which the executable file runs.
21 |
22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 | SOFTWARE.
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | nix-files
2 | ===
3 |
4 | These configurations declaratively describe both my VPS, running multiple
5 | websites and services, as well we my workstation. These machines run using the
6 | [NixOS Linux distribution](http://nixos.org).
7 |
8 | The main entry point describing the core system is `configuration.nix`; from
9 | there, each item is split categorically. Each installation will provide a link
10 | from `/etc/nixos/configuration.nix` to either `workstation/configuration.nix` or
11 | `server/configuration.nix`.
12 |
13 | ## Workstation
14 | ### Managed bits
15 | ### Non-managed bits
16 |
17 | ## Server
18 | ### Managed bits
19 | * System
20 | * GRUB, time, network, firewall, users, packages, etc
21 | * Nearly three dozen websites
22 | * Mail server
23 | * IMAP (dovecot) + SMTP (postfix) + DKIM
24 | * Rainloop web client
25 | * [safepaste](https://github.com/jeaye/safepaste) service
26 | * [jank benchmark visualizer](http://bench.jank-lang.org/) service
27 | * caldav service
28 | * SSL Certs (Let's Encrypt)
29 |
30 | ### Non-managed bits
31 | * User passwords
32 |
--------------------------------------------------------------------------------
/server/base.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | imports =
5 | [
6 | ../shared/configuration.nix
7 |
8 | ## System
9 | ./system/environment.nix
10 | ./system/network.nix
11 | ./system/security.nix
12 |
13 | ## Global programs
14 | ./program/essential.nix
15 |
16 | ## Users
17 | ./system/user.nix
18 | ];
19 | }
20 |
--------------------------------------------------------------------------------
/server/configuration.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | # TODO: Add automatic blacklist lookup
4 | # http://www.blacklistalert.org/
5 | # https://mxtoolbox.com/SuperTool.aspx?action=blacklist%3a192.241.218.198&run=toolpage
6 | # http://mail-blacklist-checker.online-domain-tools.com/
7 |
8 | {
9 | imports =
10 | [
11 | ../hardware-configuration.nix # Auto-generated by nixos
12 | ../nixos-in-place.nix # Auto-generated by nixos-in-place
13 |
14 | ## Base system
15 | ./base.nix
16 |
17 | ## Global programs
18 | ./program/admin.nix
19 |
20 | ## Users
21 | ./system/user.nix
22 |
23 | ./user/irc.nix
24 | ./user/git.nix
25 | ./user/jeaye.nix
26 | ./user/fu-er.nix
27 | ./user/okletsplay.nix
28 |
29 | ## Services
30 | ./service/acme.nix
31 | ./service/httpd.nix
32 | ./service/domain-parking.nix
33 | ./service/postfix.nix
34 | ./service/dovecot.nix
35 | ./service/opendkim.nix
36 | ./service/spamassassin.nix
37 | #./service/safepaste.nix
38 | #./service/jank-benchmark.nix
39 | ./service/fail2ban.nix
40 | ./service/radicale.nix
41 | ./service/gpg.nix
42 | ./service/jank-license.nix
43 | ./service/upload.jeaye.com-tmp.nix
44 | ./service/wordy-word.nix
45 | ./service/rainloop.nix
46 | #./service/taskserver.nix
47 |
48 | #./container/nextcloud.nix
49 | ];
50 |
51 | networking.hostName = "nixums";
52 | system.stateVersion = "19.03";
53 | }
54 |
--------------------------------------------------------------------------------
/server/container/nextcloud.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | # TODO: Update script, like rainloop has
4 |
5 | # TODO: Harden
6 | # - Disable previews (requires automatic php parsing)
7 |
8 | with import ../util/http.nix {};
9 |
10 | let
11 | hostAddr = "192.168.255.1";
12 | localAddr = "192.168.254.1";
13 | in
14 | {
15 | containers.nextcloud =
16 | {
17 | autoStart = true;
18 | privateNetwork = true;
19 | hostAddress = hostAddr;
20 | localAddress = localAddr;
21 |
22 | # Used for crypto
23 | allowedDevices = [ { modifier = "r"; node = "/dev/urandom"; } ];
24 |
25 | config = { config, pkgs, ... }:
26 | {
27 | # TODO: Share with host and bring in pam limits config
28 | security.sudo =
29 | {
30 | enable = false;
31 | wheelNeedsPassword = true;
32 | };
33 |
34 | # TODO: Share with host
35 | i18n =
36 | {
37 | consoleFont = "Lat2-Terminus16";
38 | consoleKeyMap = "us";
39 | defaultLocale = "en_US.UTF-8";
40 | };
41 | time.timeZone = "America/Los_Angeles";
42 |
43 | networking.firewall.enable = false;
44 |
45 | services.httpd =
46 | util.http.defaults // {
47 | enable = true;
48 | enablePHP = true;
49 |
50 | # TODO: Bring in redis module
51 | extraModules =
52 | [
53 | "http2" "rewrite" "headers" "env" "dir" "mime"
54 | ];
55 |
56 | hostName = "cloud.pastespace.org";
57 | documentRoot = "/etc/user/http/cloud.pastespace.org";
58 | extraConfig = util.http.defaults.extraConfig +
59 | ''
60 |
61 | DirectoryIndex index.php
62 | Options -Indexes +FollowSymLinks +ExecCGI
63 | AllowOverride All
64 | Order deny,allow
65 | Allow from all
66 | Require all granted
67 |
68 | Options +FollowSymlinks
69 | AllowOverride All
70 |
71 |
72 | Dav off
73 |
74 |
75 | SetEnv HOME /etc/user/http/cloud.pastespace.org/latest
76 | SetEnv HTTP_HOME /etc/user/http/cloud.pastespace.org/latest
77 |
78 |
79 | Options -Indexes
80 |
81 |
82 |
83 | Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
84 |
85 | '';
86 |
87 | phpOptions =
88 | ''
89 | zend_extension = ${pkgs.php}/lib/php/extensions/opcache.so
90 | opcache.enable = 1
91 | opcache.enable_cli = 1
92 | opcache.interned_strings_buffer = 8
93 | opcache.max_accelerated_files = 10000
94 | opcache.memory_consumption = 128
95 | opcache.save_comments = 1
96 | opcache.revalidate_freq = 1
97 |
98 | max_input_time = 60
99 | max_execution_time = 60
100 | '';
101 | };
102 |
103 | users.users.http =
104 | {
105 | isNormalUser = true;
106 | home = "/etc/user/http";
107 | createHome = true;
108 | };
109 |
110 | services.cron.systemCronJobs =
111 | [
112 | "*/15 * * * * http ${pkgs.php}/bin/php -f /etc/user/http/cloud.pastespace.org/latest/cron.php"
113 | ];
114 |
115 | # TODO: Automatically add config for enabling redis on NextCloud
116 | services.redis =
117 | {
118 | enable = true;
119 | bind = "127.0.0.1";
120 | #port = 0;
121 | #unixSocket = "/tmp/redis.sock";
122 | #package = pkgs.redisPhp7;
123 | extraConfig =
124 | ''
125 | #unixsocketperm 755
126 | maxclients 500
127 | '';
128 | };
129 |
130 | # TODO: Move to container util
131 | system.activationScripts =
132 | {
133 | homes =
134 | {
135 | deps = [];
136 | text = (builtins.foldl'
137 | (us: u:
138 | ''
139 | ${us}
140 | chown -R ${u.name}:users /etc/user/${u.name}
141 | '')
142 | ''
143 | chmod a+rx /etc/user
144 | ''
145 | (builtins.filter (u: u.isNormalUser)
146 | (map (key: builtins.getAttr key config.users.users)
147 | (builtins.attrNames config.users.users))));
148 | };
149 | };
150 |
151 | environment.etc =
152 | {
153 | "user/http/cloud.pastespace.org/.well-known/.manage-directory".text = "";
154 | };
155 |
156 | services.mysql =
157 | {
158 | enable = true;
159 | package = pkgs.mysql;
160 | dataDir = "/var/db/mysql";
161 | };
162 | };
163 | };
164 |
165 | services.httpd =
166 | {
167 | virtualHosts =
168 | [
169 | #{
170 | # hostName = "cloud.pastespace.org";
171 | # globalRedirect = "https://cloud.pastespace.org/";
172 | # enableSSL = false;
173 | #}
174 | {
175 | hostName = "cloud.pastespace.org";
176 | documentRoot = "/etc/user/http/cloud.pastespace.org";
177 | extraConfig =
178 | ''
179 | #SSLProxyEngine On
180 | ProxyPreserveHost Off
181 | ProxyPass /.well-known !
182 | ProxyPass /latest/ http://nextcloud.containers/latest/
183 | ProxyPassReverse /latest/ http://nextcloud.containers/latest/
184 | ''; # TODO + (defaults "cloud.pastespace.org" "cloud.pastespace.org");
185 | enableSSL = false;
186 | }
187 | ];
188 | };
189 |
190 | environment.etc =
191 | {
192 | "user/http/cloud.pastespace.org/.well-known/.manage-directory".text = "";
193 | };
194 | }
195 |
--------------------------------------------------------------------------------
/server/pkg/jank-benchmark.nix:
--------------------------------------------------------------------------------
1 | { stdenv, pkgs, fetchgit }:
2 |
3 | stdenv.mkDerivation rec
4 | {
5 | name = "jank-benchmark";
6 | src = fetchgit
7 | {
8 | url = "https://github.com/jeaye/jank-benchmark.git";
9 | deepClone = true;
10 | rev = "8262346a1e178a81640f564a8be835c83357e443";
11 | sha256 = "18bfagp15cwrh3a5gd5ww74lrdgrn0zknvcxdbr7hz999hi5h6cf";
12 | };
13 | buildInputs = [ pkgs.leiningen ];
14 | buildPhase =
15 | ''
16 | # For leiningen
17 | export HOME=$PWD
18 | export LEIN_HOME=$HOME/.lein
19 | mkdir -p $LEIN_HOME
20 | echo "{:user {:local-repo \"$LEIN_HOME\"}}" > $LEIN_HOME/profiles.clj
21 |
22 | ${pkgs.leiningen}/bin/lein uberjar
23 | '';
24 | installPhase =
25 | ''
26 | mkdir -p $out/{bin,share}
27 | install -m 0644 target/jank-benchmark.jar $out/bin/
28 | '';
29 | }
30 |
--------------------------------------------------------------------------------
/server/pkg/safepaste.nix:
--------------------------------------------------------------------------------
1 | { stdenv, pkgs, fetchgit }:
2 |
3 | stdenv.mkDerivation rec
4 | {
5 | name = "safepaste";
6 | src = fetchgit
7 | {
8 | url = "https://github.com/jeaye/safepaste.git";
9 | deepClone = true;
10 | rev = "0593b68f1d0fb2b41ea14b026bcde4d662c1dbb4";
11 | sha256 = "1dry2gqmc507jgnp7y0llml9s9mmqzimk75rw8gmxqf79j0jwhnp";
12 | };
13 | buildInputs = [ pkgs.boot pkgs.nodejs ];
14 | buildPhase =
15 | ''
16 | # For leiningen
17 | export HOME=$PWD
18 | export LEIN_HOME=$HOME/.lein
19 | mkdir -p $LEIN_HOME
20 | echo "{:user {:local-repo \"$LEIN_HOME\"}}" > $LEIN_HOME/profiles.clj
21 |
22 | ./bin/package
23 | '';
24 | installPhase =
25 | ''
26 | mkdir -p $out/{bin,share}
27 | install -m 0644 target/safepaste-standalone.jar $out/bin/
28 | install -m 0755 tool/clean-expired $out/bin/
29 | install -m 0755 tool/encrypt $out/bin/
30 | install -m 0755 tool/ban $out/bin/
31 | install -m 0644 src/paste/about $out/share/
32 | '';
33 | }
34 |
--------------------------------------------------------------------------------
/server/pkg/wordy-word.nix:
--------------------------------------------------------------------------------
1 | { stdenv, pkgs, fetchgit }:
2 |
3 | stdenv.mkDerivation rec
4 | {
5 | name = "wordy-word";
6 | src = fetchgit
7 | {
8 | url = "https://github.com/jeaye/wordy-word.git";
9 | deepClone = true;
10 | rev = "b771814d1dc5a1c7009cd587d67d73941d59d8d3";
11 | sha256 = "01xydzy6jabgdapcdq3zaz00l1wbia7g6gz83snlqf863xgfqiap";
12 | };
13 | buildInputs = [ pkgs.leiningen pkgs.wget ];
14 | buildPhase =
15 | ''
16 | # For leiningen
17 | export HOME=$PWD
18 | export LEIN_HOME=$HOME/.lein
19 | mkdir -p $LEIN_HOME
20 | echo "{:user {:local-repo \"$LEIN_HOME\"}}" > $LEIN_HOME/profiles.clj
21 |
22 | ${pkgs.leiningen}/bin/lein uberjar
23 | '';
24 | installPhase =
25 | ''
26 | mkdir -p $out/{bin,share}
27 | install -m 0644 target/uberjar/wordy-word-0.1.0-SNAPSHOT-standalone.jar $out/bin/wordy-word.jar
28 | install build-word-lists $out/bin/
29 | '';
30 | }
31 |
--------------------------------------------------------------------------------
/server/program/admin.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | # Some helpful scripts and packages for diagnostics
5 | environment.systemPackages = with pkgs;
6 | [
7 | pcre
8 | ];
9 |
10 | # TODO: Add a script for watching failed email logins
11 | # TODO: Script for daily emails sent/recieved per user
12 | environment.etc =
13 | {
14 | "admin/daily-failed-ssh-logins" =
15 | {
16 | text =
17 | ''
18 | #!/run/current-system/sw/bin/bash
19 | set -eu
20 |
21 | title="Failed SSH logins"
22 | printf "%*s\n\n" $(((''${#title}+$COLUMNS)/2)) "$title"
23 | journalctl -u sshd | grep 'Failed password' \
24 | | awk '{print $1,$2}' \
25 | | sort -k 1,1M -k 2n \
26 | | uniq -c \
27 | | sed -e 's/^\s\+//g' \
28 | -e 's/\(\S\+\) \+\(\S\+\) \+\(\S\+\)/\2 \3\t\t= \1/'
29 | '';
30 | mode = "0774";
31 | };
32 | "admin/daily-succeeded-ssh-logins" =
33 | {
34 | text =
35 | ''
36 | #!/run/current-system/sw/bin/bash
37 | set -eu
38 |
39 | title="Accepted SSH logins"
40 | printf "%*s\n\n" $(((''${#title}+$COLUMNS)/2)) "$title"
41 | journalctl -u sshd \
42 | | grep 'Accepted' \
43 | | sed 's/\(\S\+\) \(\S\+\).*for \(\S\+\) from.*/\1 \2 \3/' \
44 | | uniq \
45 | | tr '\n' '|' \
46 | | sed -e ':loop' \
47 | -e 's/\(\S\+\) \(\S\+\) \(.\+\)|\1 \2 \(\S\+\)/\1 \2 \3 \4/g' \
48 | -e 't loop' \
49 | | tr '|' '\n' \
50 | | sed -e 's/\(\S\+\) \+\(\S\+\) \+\(.\+\)/\1 \2\t\t= \3/'
51 | '';
52 | mode = "0774";
53 | };
54 | "admin/daily-port-scans" =
55 | {
56 | text =
57 | ''
58 | #!/run/current-system/sw/bin/bash
59 | set -eu
60 |
61 | title="Port scans detected"
62 | printf "%*s\n\n" $(((''${#title}+$COLUMNS)/2)) "$title"
63 | journalctl | grep 'rejected connection:' \
64 | | awk '{print $1,$2}' \
65 | | sort -k 1,1M -k 2n \
66 | | uniq -c \
67 | | sed -e 's/^\s\+//g' \
68 | -e 's/\(\S\+\) \+\(\S\+\) \+\(\S\+\)/\2 \3\t\t= \1/'
69 | '';
70 | mode = "0774";
71 | };
72 | "admin/daily-postfix-dos" =
73 | {
74 | text =
75 | ''
76 | #!/run/current-system/sw/bin/bash
77 | set -eu
78 |
79 | title="Postfix DOS attempts"
80 | printf "%*s\n\n" $(((''${#title}+$COLUMNS)/2)) "$title"
81 | journalctl -u postfix | grep 'lost connection after EHLO from' \
82 | | awk '{print $1,$2}' \
83 | | sort -k 1,1M -k 2n \
84 | | uniq -c \
85 | | sed -e 's/^\s\+//g' \
86 | -e 's/\(\S\+\) \+\(\S\+\) \+\(\S\+\)/\2 \3\t\t= \1/'
87 | '';
88 | mode = "0774";
89 | };
90 | "admin/rejected-emails" =
91 | {
92 | text =
93 | ''
94 | #!/run/current-system/sw/bin/bash
95 | set -eu
96 |
97 | title="Rejected emails"
98 | printf "%*s\n\n" $(((''${#title}+$COLUMNS)/2)) "$title"
99 |
100 | regex="reject: .+\[(.+)\]: .+ (from=<.+>) (to=<.+>) .+ (helo=<.+>).*"
101 | rejected=$(journalctl -u postfix \
102 | | pcregrep -o1 -o2 -o3 --om-separator '|' "$regex")
103 | count=$(wc -l <<< "$rejected")
104 | unique=$(sort -u <<< "$rejected" | wc -l)
105 | last=$(sed 's/|/\n\t/g' <<< "$rejected" | tail -15)
106 |
107 | printf "Total: $count\nUnique: $unique\n\n$last\n"
108 | '';
109 | mode = "0774";
110 | };
111 | "admin/daily-valid-safepaste" =
112 | {
113 | text =
114 | ''
115 | #!/run/current-system/sw/bin/bash
116 | set -eu
117 |
118 | title="Valid safepaste submissions"
119 | printf "%*s\n\n" $(((''${#title}+$COLUMNS)/2)) "$title"
120 | journalctl -u safepaste | egrep 'Paste from .+ for .+ is valid.' \
121 | | awk '{print $1,$2}' \
122 | | sort -k 1,1M -k 2n \
123 | | uniq -c \
124 | | sed -e 's/^\s\+//g' \
125 | -e 's/\(\S\+\) \+\(\S\+\) \+\(\S\+\)/\2 \3\t\t= \1/' \
126 | | tail -5
127 | '';
128 | mode = "0774";
129 | };
130 | "admin/monthly-http-access" =
131 | {
132 | text =
133 | ''
134 | #!/run/current-system/sw/bin/bash
135 | set -eu
136 |
137 | month=$1 # Mar, Jun, etc
138 | site=$2 # jeaye.com, safepaste.org, etc
139 | year=$(date +"%Y")
140 |
141 | views=$(grep "$month/$year" /var/log/httpd/access_log-$site \
142 | | pcregrep -o1 "GET (\/|\/\S*\/)(?:\?.*)? HTTP\/\S+\" 200" \
143 | | egrep -v "\.(css|png|js|txt|xml|well-known)" \
144 | | wc -l)
145 |
146 | printf "$month $year $site : $views\n"
147 | '';
148 | mode = "0774";
149 | };
150 | "admin/monthly-http-favorites" =
151 | {
152 | text =
153 | ''
154 | #!/run/current-system/sw/bin/bash
155 | set -eu
156 |
157 | month=$1 # Mar, Jun, etc
158 | site=$2 # jeaye.com, safepaste.org, etc
159 | year=$(date +"%Y")
160 |
161 | views=$(grep "$month/$year" /var/log/httpd/access_log-$site \
162 | | pcregrep -o1 "GET (\/|\/\S*\/)(?:\?.*)? HTTP\/\S+\" 200" \
163 | | egrep -v "\.(css|png|js|txt|xml|well-known)" \
164 | | sort \
165 | | uniq -c \
166 | | sort -n)
167 |
168 | echo "$month $year $site :"
169 | echo "$views"
170 | '';
171 | mode = "0774";
172 | };
173 | "admin/unban-fail2ban-ip" =
174 | {
175 | text =
176 | ''
177 | #!/run/current-system/sw/bin/bash
178 | set -eu
179 |
180 | jails=$(fail2ban-client status | pcregrep -o1 "list:\s*(\w.*)" | sed 's/,//g')
181 | for jail in $jails;
182 | do
183 | echo "Removing $1 from $jail"
184 | fail2ban-client set $jail unbanip $1 > /dev/null 2>&1 || true
185 | done
186 | '';
187 | mode = "0774";
188 | };
189 | };
190 | }
191 |
--------------------------------------------------------------------------------
/server/program/essential.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs;
5 | [
6 | vim
7 | wget
8 | elinks
9 | unzip
10 | git
11 | htop
12 | #bashCompletion
13 | telnet
14 | traceroute
15 | nix-repl
16 | file
17 | ];
18 | }
19 |
--------------------------------------------------------------------------------
/server/service/acme.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | with import ../util/acme.nix {};
4 |
5 | let
6 | global-email = "contact@jeaye.com";
7 | in
8 | {
9 | environment.systemPackages = [ pkgs.simp_le ];
10 |
11 | security.acme =
12 | {
13 | directory = util.acme.directory;
14 |
15 | # TODO: Combine these subdomains where possible
16 | certs =
17 | {
18 | "pastespace.org" =
19 | {
20 | webroot = "/etc/user/http/pastespace.org";
21 | extraDomains =
22 | {
23 | "www.pastespace.org" = null;
24 | "mail.pastespace.org" = null;
25 | #"cloud.pastespace.org:/etc/user/http/cloud.pastespace.org" = null;
26 | "webmail.pastespace.org:/etc/user/http/webmail.pastespace.org" = null;
27 | };
28 | email = global-email;
29 | plugins = util.acme.plugins;
30 | postRun = util.acme.post-run + "systemctl restart dovecot2;";
31 | };
32 | "safepaste.org" =
33 | {
34 | webroot = "/etc/user/http/safepaste.org";
35 | extraDomains =
36 | {
37 | "www.safepaste.org" = null;
38 | };
39 | email = global-email;
40 | plugins = util.acme.plugins;
41 | postRun = util.acme.post-run;
42 | };
43 | "jeaye.com" =
44 | {
45 | webroot = "/etc/user/http/jeaye.com";
46 | extraDomains =
47 | { "www.jeaye.com" = null; };
48 | email = global-email;
49 | plugins = util.acme.plugins;
50 | postRun = util.acme.post-run;
51 | };
52 | "upload.jeaye.com" =
53 | {
54 | webroot = "/etc/user/http/upload.jeaye.com";
55 | extraDomains =
56 | { "upload.jeaye.com" = null; };
57 | email = global-email;
58 | plugins = util.acme.plugins;
59 | postRun = util.acme.post-run;
60 | };
61 | "jank-lang.org" =
62 | {
63 | webroot = "/etc/user/http/jank-lang.org";
64 | extraDomains =
65 | {
66 | "www.jank-lang.org" = null;
67 | "bench.jank-lang.org" = null;
68 | };
69 | email = global-email;
70 | plugins = util.acme.plugins;
71 | postRun = util.acme.post-run;
72 | };
73 | "fu-er.com" =
74 | {
75 | webroot = "/etc/user/http/fu-er.com";
76 | extraDomains =
77 | {
78 | "www.fu-er.com" = null;
79 | };
80 | email = global-email;
81 | plugins = util.acme.plugins;
82 | postRun = util.acme.post-run;
83 | };
84 | "penelope-art.com" =
85 | {
86 | webroot = "/etc/user/http/penelope-art.com";
87 | extraDomains =
88 | {
89 | "www.penelope-art.com" = null;
90 | };
91 | email = global-email;
92 | plugins = util.acme.plugins;
93 | postRun = util.acme.post-run;
94 | };
95 | "penny-art.com" =
96 | {
97 | webroot = "/etc/user/http/penny-art.com";
98 | extraDomains =
99 | {
100 | "www.penny-art.com" = null;
101 | };
102 | email = global-email;
103 | plugins = util.acme.plugins;
104 | postRun = util.acme.post-run;
105 | };
106 | };
107 | };
108 | }
109 |
--------------------------------------------------------------------------------
/server/service/data/park-index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | %%domain%% is for sale
8 |
9 |
10 |
69 |
93 |
94 |
95 |
96 |
97 |
98 |
%%domain%%
99 |
This domain is for sale.
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/server/service/data/upgrade-rainloop:
--------------------------------------------------------------------------------
1 | #!/run/current-system/sw/bin/bash
2 |
3 | set -eu -o pipefail
4 |
5 | zip_file=rainloop-community-latest.zip
6 | signature_file=$zip_file.asc
7 | remote_webmail=https://www.rainloop.net/repository/webmail
8 | local_webmail=/etc/user/http/webmail.pastespace.org
9 |
10 | printf "RainLoop: checking for upgrades... "
11 | new_zip_signature=$(curl -s "$remote_webmail/$signature_file" || true)
12 | old_zip_signature=$(cat "$local_webmail/latest/$signature_file" || true)
13 |
14 | if [ "x$new_zip_signature" == "x" ];
15 | then
16 | echo "no internet"
17 | exit 0
18 | fi
19 |
20 | if [ "$new_zip_signature" != "$old_zip_signature" ];
21 | then
22 | echo "found"
23 | echo "RainLoop: upgrading..."
24 | temp_dir=$(mktemp -d)
25 | pushd "$temp_dir"
26 | gpg2 --import <(curl -s "https://www.rainloop.net/repository/RainLoop.asc")
27 |
28 | # Download new version
29 | wget "$remote_webmail/$zip_file"
30 | gpg2 --verify <(echo "$new_zip_signature") "$zip_file"
31 |
32 | # Start from the latest, if it's there
33 | if [ -d "$local_webmail/latest" ];
34 | then
35 | rsync -av "$local_webmail/latest/" .
36 | fi
37 |
38 | unzip -o "$zip_file"
39 | rm "$zip_file"
40 |
41 | echo "$new_zip_signature" > "$signature_file"
42 | popd
43 |
44 | new_version=$(date +'version-%Y-%m-%d.%H:%M:%S')
45 | new_path=$local_webmail/$new_version
46 | if [ -d "$new_path" ];
47 | then
48 | echo "RainLoop: directory already exists: $new_path"
49 | exit 1
50 | fi
51 |
52 | # Move the new version into place and setup permissions
53 | mv "$temp_dir" "$new_path"
54 | find "$new_path" -type d -exec chmod 755 {} \;
55 | find "$new_path" -type f -exec chmod 644 {} \;
56 | chown -R http:users "$new_path"
57 |
58 | # Atomically link/upgrade
59 | ln -sfn "$new_path" "$local_webmail/latest"
60 |
61 | echo "Rainloop: upgrade complete"
62 | else
63 | echo "not found"
64 | fi
65 |
--------------------------------------------------------------------------------
/server/service/domain-parking.nix:
--------------------------------------------------------------------------------
1 | { lib, config, pkgs, ... }:
2 |
3 | let
4 | domains =
5 | [
6 | "anonymust.org"
7 | "anylist.io"
8 | "autocoupon.org"
9 | "bankapp.io"
10 | "candycapitalist.com"
11 | "candycapitalist.org"
12 | "clojure-atlas.org"
13 | "cpp-atlas.org"
14 | "date-ver.org"
15 | "datever.org"
16 | "discipline-lang.com"
17 | "discipline-lang.org"
18 | "discipline.sh"
19 | "farmware.io"
20 | "furthington.com"
21 | "helderman.io"
22 | "history-proxy.org"
23 | "idiolect.org"
24 | "idiolisp.com"
25 | "idiolisp.io"
26 | "idiolisp.org"
27 | "jank-platform.org"
28 | "jank.wiki"
29 | "jeaye.dev"
30 | "jeaye.io"
31 | "orthodox-lang.com"
32 | "orthodox-lang.io"
33 | "orthodox-lang.org"
34 | "penny.cafe"
35 | "penny.ink"
36 | "penny.poker"
37 | "penny.works"
38 | "penny.wtf"
39 | "polyvore.io"
40 | "preplist.io"
41 | "preplist.org"
42 | "puretorrent.org"
43 | "safetybox.org"
44 | "spamcan.org"
45 | "text-box.org"
46 | "texta.io"
47 | "trustcoin.org"
48 | "tunnelvpn.io"
49 | "tunnelvpn.org"
50 | "univps.org"
51 | "unorthodox-lang.com"
52 | "unorthodox-lang.io"
53 | "unorthodox-lang.org"
54 | "unorthodox.io"
55 | "vingtsun.io"
56 | "wingtsun.io"
57 | "zenlock.io"
58 | "zenlock.org"
59 | "zentrain.io"
60 | ];
61 | makeVirtualHost = domain:
62 | (builtins.nameValuePair domain {
63 | serverAliases = [("www." + domain)];
64 | enableSSL = false;
65 | documentRoot = "/etc/user/http/" + domain;
66 | });
67 | index = builtins.readFile ./data/park-index.html;
68 | makeIndexFile = domain:
69 | {
70 | name = "user/http/" + domain + "/index.html";
71 | value =
72 | {
73 | text = builtins.replaceStrings ["%%domain%%"] [domain] index;
74 | };
75 | };
76 | in
77 | {
78 | services.httpd.virtualHosts = (builtins.listToAttrs (map makeVirtualHost domains));
79 | environment.etc = (builtins.listToAttrs (map makeIndexFile domains));
80 | }
81 |
--------------------------------------------------------------------------------
/server/service/dovecot.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | services.dovecot2 =
5 | {
6 | enable = true;
7 | enableImap = true;
8 | enablePop3 = false;
9 | mailLocation = "maildir:~/Maildir";
10 | sslServerCert = "/var/lib/acme/pastespace.org/cert.pem";
11 | sslServerKey = "/var/lib/acme/pastespace.org/key.pem";
12 | sslCACert = "/var/lib/acme/pastespace.org/chain.pem";
13 | extraConfig =
14 | ''
15 | ssl = required
16 |
17 | protocol imap {
18 | mail_plugins = $mail_plugins autocreate
19 | }
20 |
21 | # TODO: Update to namespaces
22 | plugin {
23 | autocreate = Trash
24 | autocreate2 = Sent
25 | autocreate3 = Drafts
26 | autocreate4 = Spam
27 | autosubscribe = Trash
28 | autosubscribe2 = Sent
29 | autosubscribe3 = Drafts
30 | autosubscribe4 = Spam
31 | }
32 |
33 | service auth {
34 | unix_listener /var/lib/postfix/queue/private/auth {
35 | mode = 0660
36 | user = postfix
37 | group = postfix
38 | }
39 | }
40 | '';
41 | };
42 |
43 | networking.firewall =
44 | {
45 | allowedTCPPorts =
46 | [
47 | 143 # imap
48 | 993 # imap
49 | ];
50 | };
51 | }
52 |
--------------------------------------------------------------------------------
/server/service/fail2ban.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | nixpkgs.config =
5 | {
6 | packageOverrides = pkgs: rec
7 | {
8 | fail2ban = pkgs.fail2ban.overrideDerivation (oldAttrs :
9 | {
10 | src = pkgs.fetchzip
11 | {
12 | name = "fail2ban-0.9.3-src";
13 | url = "https://github.com/fail2ban/fail2ban/archive/0.9.3.tar.gz";
14 | sha256 = "1pwgr56i6l6wh2ap8b5vknxgsscfzjqy2nmd1c3vzdii5kf72j0f";
15 | };
16 | });
17 | };
18 | };
19 |
20 | services.fail2ban =
21 | {
22 | enable = true;
23 |
24 | jails.DEFAULT =
25 | ''
26 | bantime = 3600
27 | '';
28 | jails.sshd =
29 | ''
30 | filter = sshd
31 | maxretry = 4
32 | action = iptables[name=ssh, port=ssh, protocol=tcp]
33 | enabled = true
34 | '';
35 | jails.sshd-ddos =
36 | ''
37 | filter = sshd-ddos
38 | maxretry = 2
39 | action = iptables[name=ssh, port=ssh, protocol=tcp]
40 | enabled = true
41 | '';
42 | jails.port-scan =
43 | ''
44 | filter = port-scan
45 | action = iptables-allports[name=port-scan]
46 | maxretry = 2
47 | bantime = 7200
48 | enabled = true
49 | '';
50 | # TODO: Move these to their appropriate files
51 | jails.postfix =
52 | ''
53 | filter = postfix
54 | maxretry = 3
55 | action = iptables[name=postfix, port=smtp, protocol=tcp]
56 | enabled = false
57 | '';
58 | jails.postfix-sasl =
59 | ''
60 | filter = postfix-sasl
61 | maxretry = 3
62 | action = iptables[name=postfix, port=smtp, protocol=tcp]
63 | enabled = true
64 | '';
65 | jails.postfix-custom =
66 | ''
67 | filter = postfix-custom
68 | maxretry = 3
69 | action = iptables[name=postfix, port=submission, protocol=tcp]
70 | iptables[name=postfix, port=smtp, protocol=tcp]
71 | bantime = 7200
72 | enabled = true
73 | '';
74 | };
75 | environment.etc."fail2ban/filter.d/port-scan.conf".text =
76 | ''
77 | [Definition]
78 | failregex = rejected connection: .* SRC=
79 | '';
80 | environment.etc."fail2ban/filter.d/postfix-custom.conf".text =
81 | ''
82 | [Definition]
83 | failregex = lost connection after (EHLO|AUTH) from \S+\[\]
84 | reject: RCPT from \S+\[\]: 450 4.7.1
85 | reject: RCPT from \S+\[\]: 554 5\.7\.1
86 | reject: VRFY from \S+\[\]: 550 5\.1\.1
87 | improper command pipelining after \S+ from [^[]*\[\]:?
88 | '';
89 |
90 | # Limit stack size to reduce memory usage
91 | systemd.services.fail2ban.serviceConfig.LimitSTACK = 256 * 1024;
92 | }
93 |
--------------------------------------------------------------------------------
/server/service/gpg.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | # Refresh keys daily
5 | services.cron.systemCronJobs =
6 | [
7 | "0 23 * * * jeaye /etc/user/jeaye/bin/gpg --refresh-keys > /dev/null"
8 | ];
9 |
10 | # XXX: We need to import the private key
11 | environment.etc."user/http/upload.jeaye.com/6C61E510.asc".text =
12 | ''-----BEGIN PGP PUBLIC KEY BLOCK-----
13 | Version: GnuPG v2
14 |
15 | mQENBFaWCMYBCAChLz9/nVXLdrNIhvHD4Kg4DOxTp7XaEXEVM9oKTnxbO49ZKl9u
16 | 2tuKaRtyL23BBfKtpm7dBkjBQDOyX4+92PxSlJgB0UC169jExRNfqU2b65bvNHzS
17 | 2jzRsuJ/B6u+FmaMGGXuv1UItWxlnD7c5aD1WdpthcewiED2SLCcp2fw5rNv6gw1
18 | uvEzRO+x6SAzmRcoDQF49Dd6U68z9X+c74n1HAKnQT5/l4ftZh/MK6/VbiGMHWbF
19 | I5U7/AtYQAJC4yFf6nmJb4Z7RiaGyiLyBdj1gW1de/a1YwJcGMTrpOnZa0ZxCwgE
20 | S63/hNs23AFI1dSpG3aEYDOkCe8iYB5nlzyFABEBAAG0GUplYXllIDxjb250YWN0
21 | QGplYXllLmNvbT6JATcEEwEIACEFAlaWCMYCGwMFCwkIBwIGFQgJCgsCBBYCAwEC
22 | HgECF4AACgkQp3/8hWxh5RDf1Af+PYhJ/w/mFbkE/BH1r6zOVA8o+ikTxTvGcKZo
23 | hiiJ6vPfaI1fUsPnwY/E6o6xz13OOHtvhb2844v4fc8Q1mOo6KQbjbU+HC/M4R6u
24 | DT1vwgvGftJSFAkV9cpVcdxK9/dCCXLudD17Lt4xPjLSdi1ntdlEWX5izlhjb/El
25 | /uY7OWJ/aa1f9DM8tTVE7kaOTtre5zx+ojZQJnl60CzFP2OTlQunE52r5ZBPEsIu
26 | rf2LUh2oEQNE6g5wQ7QTinE8Jp/n/Ibeuw3GdFSeRo7IRVdSsxKEi6nb2Elzs1nv
27 | CjWCML0LqXJDMkNCLX5Q86tx818lkFgblBU4Xi6y5yFNwRgn8LQeSmVheWUgPGNv
28 | bnRhY3RAcGFzdGVzcGFjZS5vcmc+iQE3BBMBCAAhBQJWliJnAhsDBQsJCAcCBhUI
29 | CQoLAgQWAgMBAh4BAheAAAoJEKd//IVsYeUQ7v4H/19Vu/HoE0rYyf8FY79oFT3D
30 | aoAjXZbGfLqJPso7FqteiI9nGjv0H7ZUfOWOxlPankItVBCAkx0bDQ3LaZAtP+Uv
31 | uCzqNB8+bOwO7maKy0aJVi/esDXzG1OnGww1jF2G4wkclNpRptnRgU5EKH2mlpSV
32 | SxX+zuxQ+BsMOux0it07HNfO9tazeyHl4xShf24XuSWeKXETbC0TK1MY+EDKpVyp
33 | EKJkzhzdF1RL7/aF8eVobW7EWCnyr/Ph0+68HWTcolReNXDouWJff1FLjqsuXqXF
34 | scLaMl3u136NIA9VpJOzm/Lm287uECr75nHZy2Li90RTRBPxKeYNoVCQq+1Kn4m5
35 | AQ0EVpYIxgEIAL+kj13aMEYXOTsunr7uU55OwlxdiV2Yo7GmnORj4Gezq5a6CZYz
36 | Z8CXkwHsVy4Q9KBPxPUr1h1UasA2DLG20vdoxhHrmZFiGAKauq7aghLMVfFv3q9Z
37 | cWrj9J0EqQGr+m/dcuBfCxlIfXgu3NJJK2gej+HsIBq4U5JpMJFqN5faUzOPjusT
38 | mAgNgQrsLKP5QchghlgM6cueS0O+PJ5GuSNQvJ6bDlfNsow43DohuDWlQsfpbQYL
39 | pveCGmpCM2UHzbIregPsKJEVSvk2kC6izmepEiinNBffhfxBVEY07Tg+aMbUtbVI
40 | Cjp7ufdi5HGLYUUO3vUT94g0UVROmnCSjL0AEQEAAYkBHwQYAQgACQUCVpYIxgIb
41 | DAAKCRCnf/yFbGHlEBwnB/0cMpUnaxHZpn9AVSkSbwF+3v0t5fa0F/Z5wATqU0eT
42 | 9TR9a4Grsh9dpLUJ634yryA/aaQBxdJ4s8NK8h8VDDKEb86PdfWTU6psXvHG7yfH
43 | o11+onQitAj7BHZyp6b6q10XOfW6tiT3cVAFhUMYPWhDqv1Oq44MB60MZmt7sQFc
44 | EKQIyGau+FdcKfN6IIufUveq/uYXT9YuFbEd2k774LusCf8tBqJ+9ehy9YeUSxBl
45 | tkz7tldLlyD9v0N5TSBPm2T0wI6Ih30HA05v/vAdGXovxBJI7kLQ6Z7aPBDxFQX1
46 | ac4UGQmr6bAUue97EAZkpmONhTW6szTM+PTNAFQ2HmsT
47 | =j3xc
48 | -----END PGP PUBLIC KEY BLOCK-----'';
49 | }
50 |
--------------------------------------------------------------------------------
/server/service/httpd.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | with import ../util/http.nix {};
4 |
5 | {
6 | services.httpd =
7 | util.http.defaults // {
8 | enable = true;
9 |
10 | extraModules =
11 | [
12 | "http2" "proxy" "proxy_http"
13 | { name = "php7"; path = "${pkgs.php}/modules/libphp7.so"; }
14 | ];
15 |
16 | # TODO: Add proxy helper fn
17 | virtualHosts =
18 | {
19 | "pastespace.org" =
20 | {
21 | serverAliases =
22 | [
23 | "www.pastespace.org"
24 | "mail.pastespace.org"
25 | ];
26 | forceSSL = true;
27 | documentRoot = "/etc/user/http/pastespace.org";
28 | extraConfig =
29 | ''
30 | # XXX: Requires manual creation using htpasswd
31 |
32 | AuthType Basic
33 | AuthName "Restricted Calendar"
34 | AuthBasicProvider file
35 | AuthUserFile /etc/user/http/calendar-auth-users
36 | Require valid-user
37 | RequestHeader set X-Script-Name "/calendar"
38 |
39 |
40 | RedirectMatch 301 "^\/(?!\.well-known|calendar).*" https://jeaye.com
41 |
42 | SSLProxyEngine On
43 | ProxyPreserveHost Off
44 | ProxyPass /.well-known !
45 | ProxyPass /calendar http://localhost:5232/
46 | ProxyPassReverse /calendar http://localhost:5232/
47 | '' + (util.http.helpers.withSSL "pastespace.org" "pastespace.org");
48 | enableSSL = true;
49 | }
50 | {
51 | hostName = "webmail.pastespace.org";
52 | globalRedirect = "https://webmail.pastespace.org/";
53 | enableSSL = false;
54 | }
55 | {
56 | hostName = "webmail.pastespace.org";
57 | documentRoot = "/etc/user/http/webmail.pastespace.org";
58 | extraConfig =
59 | ''
60 |
61 | DirectoryIndex index.php
62 | Options -Indexes +FollowSymLinks +ExecCGI
63 | AllowOverride All
64 | Order deny,allow
65 | Allow from all
66 | Require all granted
67 |
68 |
69 | Options -Indexes
70 | Deny from all
71 |
72 | '' + (util.http.helpers.withSSL "webmail.pastespace.org" "pastespace.org");
73 | enableSSL = true;
74 | }
75 | {
76 | hostName = "safepaste.org";
77 | serverAliases =
78 | [
79 | "www.safepaste.org"
80 | ];
81 | globalRedirect = "https://safepaste.org/";
82 | enableSSL = false;
83 | }
84 | {
85 | hostName = "safepaste.org";
86 | documentRoot = "/etc/user/http/safepaste.org";
87 | extraConfig =
88 | ''
89 | SSLProxyEngine On
90 | ProxyPreserveHost Off
91 | ProxyPass /.well-known !
92 | ProxyPass / http://localhost:3000/
93 | ProxyPassReverse / http://localhost:3000/
94 | '' + (util.http.helpers.withSSL "safepaste.org" "safepaste.org");
95 | enableSSL = true;
96 | }
97 | {
98 | hostName = "upload.jeaye.com";
99 | globalRedirect = "https://upload.jeaye.com/";
100 | }
101 | {
102 | hostName = "upload.jeaye.com";
103 | documentRoot = "/etc/user/http/upload.jeaye.com";
104 | extraConfig =
105 | ''
106 |
107 | Options +Indexes
108 | IndexOptions FancyIndexing SuppressDescription NameWidth=*
109 |
110 | Protocols http/1.1
111 | '' + (util.http.helpers.withSSL "upload.jeaye.com" "upload.jeaye.com");
112 | enableSSL = true;
113 | }
114 | {
115 | hostName = "jeaye.com";
116 | serverAliases = [ "www.jeaye.com" ];
117 | globalRedirect = "https://jeaye.com/";
118 | }
119 | {
120 | hostName = "jeaye.com";
121 | serverAliases = [ "www.jeaye.com" ];
122 | documentRoot = "/etc/user/http/jeaye.com";
123 | extraConfig =
124 | ''
125 | SSLProxyEngine On
126 | ProxyPreserveHost Off
127 | ProxyPass /.well-known !
128 | ProxyPass / https://jeaye.github.io/jeaye.com/
129 | ProxyPassReverse / https://jeaye.github.io/jeaye.com/
130 | ProxyPassReverse / http://jeaye.github.io/jeaye.com/
131 | '' + (util.http.helpers.withSSL "jeaye.com" "jeaye.com");
132 | enableSSL = true;
133 | }
134 | {
135 | hostName = "jank-lang.org";
136 | serverAliases = [ "www.jank-lang.org" ];
137 | globalRedirect = "https://jank-lang.org/";
138 | enableSSL = false;
139 | }
140 | {
141 | hostName = "jank-lang.org";
142 | serverAliases = [ "www.jank-lang.org" ];
143 | documentRoot = "/etc/user/http/jank-lang.org";
144 | extraConfig =
145 | ''
146 | RedirectMatch 301 "^\/(?!\.well-known).*" https://github.com/jeaye/jank
147 | '' + (util.http.helpers.withSSL "jank-lang.org" "jank-lang.org");
148 | enableSSL = true;
149 | }
150 | {
151 | hostName = "bench.jank-lang.org";
152 | globalRedirect = "https://bench.jank-lang.org/";
153 | enableSSL = false;
154 | }
155 | {
156 | hostName = "bench.jank-lang.org";
157 | documentRoot = "/etc/user/http/jank-lang.org";
158 | extraConfig =
159 | ''
160 | SSLProxyEngine On
161 | ProxyPreserveHost Off
162 | ProxyPass /.well-known !
163 | ProxyPass / http://localhost:3001/
164 | ProxyPassReverse / http://localhost:3001/
165 | '' + (util.http.helpers.withSSL "jank-lang.org" "jank-lang.org");
166 | enableSSL = true;
167 | }
168 | {
169 | hostName = "fu-er.com";
170 | serverAliases = [ "www.fu-er.com" ];
171 | globalRedirect = "https://fu-er.com/";
172 | enableSSL = false;
173 | }
174 | {
175 | hostName = "fu-er.com";
176 | serverAliases = [ "www.fu-er.com" ];
177 | documentRoot = "/etc/user/http/fu-er.com";
178 | extraConfig =
179 | ''
180 | '' + (util.http.helpers.withSSL "fu-er.com" "fu-er.com");
181 | enableSSL = true;
182 | }
183 | {
184 | hostName = "penelope-art.com";
185 | serverAliases = [ "www.penelope-art.com" ];
186 | globalRedirect = "https://penelope-art.com/";
187 | enableSSL = false;
188 | }
189 | {
190 | hostName = "penelope-art.com";
191 | serverAliases = [ "www.penelope-art.com" ];
192 | documentRoot = "/etc/user/http/penelope-art.com";
193 | extraConfig =
194 | ''
195 | DirectoryIndex resume.pdf
196 | '' + (util.http.helpers.withSSL "penelope-art.com" "penelope-art.com");
197 | enableSSL = true;
198 | }
199 | {
200 | hostName = "penny-art.com";
201 | serverAliases = [ "www.penny-art.com" ];
202 | globalRedirect = "https://penny-art.com/";
203 | enableSSL = false;
204 | }
205 | {
206 | hostName = "penny-art.com";
207 | serverAliases = [ "www.penny-art.com" ];
208 | documentRoot = "/etc/user/http/penny-art.com";
209 | extraConfig =
210 | ''
211 | RedirectMatch 301 "^\/(?!\.well-known).*" https://penny.artstation.com/
212 | '' + (util.http.helpers.withSSL "penny-art.com" "penny-art.com");
213 | enableSSL = true;
214 | }
215 | };
216 | };
217 |
218 | users.users.http =
219 | {
220 | isNormalUser = true;
221 | home = "/etc/user/http";
222 | };
223 |
224 | environment.etc =
225 | {
226 | "user/http/pastespace.org/.well-known/.manage-directory".text = "";
227 | "user/http/webmail.pastespace.org/.well-known/.manage-directory".text = "";
228 | "user/http/safepaste.org/.well-known/.manage-directory".text = "";
229 | "user/http/jeaye.com/.well-known/.manage-directory".text = "";
230 | "user/http/jank-lang.org/.well-known/.manage-directory".text = "";
231 | "user/http/upload.jeaye.com/.well-known/.manage-directory".text = "";
232 | "user/http/upload.jeaye.com/tmp/.manage-directory".text = "";
233 | "user/http/fu-er.com/.well-known/.manage-directory".text = "";
234 | "user/http/penelope-art.com/.well-known/.manage-directory".text = "";
235 | "user/http/penny-art.com/.well-known/.manage-directory".text = "";
236 | };
237 |
238 | networking.firewall =
239 | {
240 | allowedTCPPorts =
241 | [
242 | 80 # http
243 | 443 # https
244 | ];
245 | };
246 | }
247 |
--------------------------------------------------------------------------------
/server/service/jank-benchmark.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages =
5 | [
6 | pkgs.leiningen
7 | pkgs.openjdk
8 | pkgs.gcc
9 | ];
10 |
11 | nixpkgs.config =
12 | {
13 | packageOverrides = pkgs: rec
14 | {
15 | jank-benchmark = pkgs.callPackage ../pkg/jank-benchmark.nix { };
16 | };
17 | };
18 |
19 | environment.etc."user/jank-benchmark/run-server" =
20 | {
21 | text =
22 | ''
23 | #!/run/current-system/sw/bin/bash
24 | set -eu
25 | export PATH=${pkgs.git}/bin:${pkgs.leiningen}/bin:${pkgs.gcc}/bin:$PATH
26 |
27 | ${pkgs.openjdk}/bin/java -jar ${pkgs.jank-benchmark}/bin/jank-benchmark.jar
28 | '';
29 | mode = "0775";
30 | };
31 |
32 | systemd.services.jank-benchmark =
33 | {
34 | wantedBy = [ "multi-user.target" ];
35 | after = [ "network.target" ];
36 | serviceConfig =
37 | {
38 | User = "jank-benchmark";
39 | WorkingDirectory = "/etc/user/jank-benchmark";
40 | ExecStart = "/etc/user/jank-benchmark/run-server";
41 | };
42 | };
43 |
44 | users.users.jank-benchmark =
45 | {
46 | isNormalUser = false;
47 | home = "/etc/user/jank-benchmark";
48 | createHome = true;
49 | };
50 |
51 | system.activationScripts =
52 | {
53 | jank-benchmark-home =
54 | {
55 | deps = [];
56 | text =
57 | ''
58 | chown -R jank-benchmark:users /etc/user/jank-benchmark
59 | '';
60 | };
61 | };
62 |
63 | networking.firewall.allowedTCPPorts = [ 3001 ];
64 | }
65 |
--------------------------------------------------------------------------------
/server/service/jank-license.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.etc."user/http/upload.jeaye.com/jank-license".text =
5 | ''Redistribution and use in source and binary forms, with or without
6 | modification, are permitted, free of charge, provided that the following
7 | conditions are met:
8 |
9 | Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | Redistributions in any form must be accompanied by information on how to obtain
17 | complete source code for the distributed software and any accompanying software
18 | that uses the distributed software. The source code must either be included in
19 | the distribution or be available free of charge. For an executable file,
20 | complete source code means the source code for all modules it contains. It does
21 | not include source code for modules or files that typically accompany the major
22 | components of the operating system on which the executable file runs.
23 |
24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 | SOFTWARE.'';
31 | }
32 |
--------------------------------------------------------------------------------
/server/service/opendkim.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs;
5 | [
6 | opendkim
7 | openssl
8 | ];
9 |
10 | environment.etc =
11 | {
12 | "opendkim/opendkim.conf" =
13 | {
14 | text =
15 | ''
16 | Domain pastespace.org safepaste.org jeaye.com fu-er.com penelope-art.com penny-art.com
17 | Selector mail
18 | KeyTable refile:/etc/opendkim/key-table
19 | SigningTable refile:/etc/opendkim/signing-table
20 | Socket local:/var/run/opendkim/opendkim.sock
21 | ReportAddress postmaster@pastespace.org
22 | RequireSafeKeys False
23 | UserID opendkim:opendkim
24 |
25 | AutoRestart Yes
26 | AutoRestartRate 10/1h
27 | UMask 002
28 | Syslog yes
29 | SyslogSuccess Yes
30 | LogWhy Yes
31 |
32 | Canonicalization relaxed/simple
33 | '';
34 | };
35 | "opendkim/key-table" =
36 | {
37 | text =
38 | ''
39 | mail._domainkey.pastespace.org pastespace.org:mail:/etc/opendkim/keys/pastespace.org/mail.private
40 | mail._domainkey.safepaste.org safepaste.org:mail:/etc/opendkim/keys/safepaste.org/mail.private
41 | mail._domainkey.jeaye.com jeaye.com:mail:/etc/opendkim/keys/jeaye.com/mail.private
42 | mail._domainkey.fu-er.com fu-er.com:mail:/etc/opendkim/keys/fu-er.com/mail.private
43 | mail._domainkey.penelope-art.com penelope-art.com:mail:/etc/opendkim/keys/penelope-art.com/mail.private
44 | mail._domainkey.penny-art.com penny-art.com:mail:/etc/opendkim/keys/penny-art.com/mail.private
45 | '';
46 | };
47 | "opendkim/signing-table" =
48 | {
49 | text =
50 | ''
51 | *@pastespace.org mail._domainkey.pastespace.org
52 | *@safepaste.org mail._domainkey.safepaste.org
53 | *@jeaye.com mail._domainkey.jeaye.com
54 | *@fu-er.com mail._domainkey.fu-er.com
55 | *@penelope-art.com mail._domainkey.penelope-art.com
56 | *@penny-art.com mail._domainkey.penny-art.com
57 | '';
58 | };
59 | };
60 |
61 | system.activationScripts =
62 | {
63 | opendkim =
64 | {
65 | deps = [];
66 | text =
67 | ''
68 | export PATH=${pkgs.stdenv}/bin:${pkgs.openssl}/bin:${pkgs.gnused}/bin:${pkgs.gnugrep}/bin:$PATH
69 | mkdir -p /var/run/opendkim
70 | chown -R opendkim:opendkim /var/run/opendkim
71 |
72 | work()
73 | {
74 | if [ ! -f /etc/opendkim/keys/$1/mail.private ];
75 | then
76 | mkdir -p /etc/opendkim/keys/$1
77 | ${pkgs.opendkim}/bin/opendkim-genkey -d $1 -D /etc/opendkim/keys/$1/ -s mail -r -t
78 | fi
79 | }
80 | for domain in pastespace.org safepaste.org jeaye.com fu-er.com penelope-art.com penny-art.com;
81 | do
82 | work $domain
83 | done
84 |
85 | chmod -R 700 /etc/opendkim/keys
86 | chown -R opendkim:opendkim /etc/opendkim/keys
87 | '';
88 | };
89 | };
90 |
91 | systemd.services.opendkim =
92 | {
93 | wantedBy = [ "multi-user.target" ];
94 | after = [ "network.target" ];
95 | serviceConfig =
96 | {
97 | ExecStart =
98 | ''
99 | ${pkgs.opendkim}/bin/opendkim -f -x /etc/opendkim/opendkim.conf
100 | '';
101 | };
102 | };
103 |
104 | users.users.opendkim =
105 | {
106 | isSystemUser = true;
107 | extraGroups = [ "opendkim" ];
108 | };
109 | users.users.postfix.extraGroups = [ "opendkim" ];
110 | users.groups.opendkim = {};
111 | }
112 |
--------------------------------------------------------------------------------
/server/service/postfix.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs;
5 | [
6 | procmail
7 | ];
8 |
9 | services.postfix = rec
10 | {
11 | enable = true;
12 | domain = "pastespace.org";
13 | hostname = "${domain}";
14 | origin = "${domain}";
15 | destination =
16 | [
17 | "${hostname}"
18 | "${domain}"
19 | "localhost.${domain}"
20 | "localhost"
21 | ];
22 | networksStyle = "host";
23 | relayDomains = [];
24 | virtual =
25 | ''
26 | contact@pastespace.org jeaye
27 | domain@pastespace.org jeaye
28 | contact@safepaste.org jeaye
29 | contact@arrownext.com jeaye
30 | contact@jeaye.com jeaye
31 | contact@trustcoin.org jeaye
32 |
33 | contact@furthington.com jeaye
34 | support@furthington.com jeaye
35 |
36 | spam@pastespace.org jeaye
37 | junk@pastespace.org jeaye
38 | junk@jeaye.com jeaye
39 |
40 | contact@fu-er.com fu-er
41 | contact@penelope-art.com fu-er
42 | contact@penny-art.com fu-er
43 | kitty@pastespace.org fu-er
44 | '';
45 | postmasterAlias = "root";
46 | rootAlias = "jeaye";
47 |
48 | extraAliases =
49 | ''
50 | # Basic system aliases -- these MUST be present
51 | MAILER-DAEMON: postmaster
52 |
53 | # General redirections for pseudo accounts
54 | bin: root
55 | daemon: root
56 | named: root
57 | nobody: root
58 | uucp: root
59 | www: root
60 | ftp-bugs: root
61 | postfix: root
62 |
63 | # Well-known aliases
64 | manager: root
65 | dumper: root
66 | operator: root
67 | abuse: postmaster
68 |
69 | # Trap decode to catch security attacks
70 | decode: root
71 |
72 | # Local users
73 | safepaste: jeaye
74 | '';
75 | extraConfig =
76 | ''
77 | home_mailbox = Maildir/
78 | virtual_alias_domains = jeaye.com safepaste.org trustcoin.org furthington.com fu-er.com penelope-art.com penny-art.com
79 |
80 | # Max email size ~20MB
81 | message_size_limit = 20480000
82 |
83 | # Prevent others from checking for valid emails
84 | disable_vrfy_command = yes
85 |
86 | # Deliver through procmail
87 | mailbox_command = ${pkgs.procmail}/bin/procmail -t -a "$EXTENSION"
88 |
89 | # Security
90 | smtpd_use_tls = yes
91 | smtpd_tls_cert_file = /var/lib/acme/pastespace.org/cert.pem
92 | smtpd_tls_key_file = /var/lib/acme/pastespace.org/key.pem
93 | smtpd_tls_session_cache_database = btree:''${queue_directory}/smtpd_scache
94 | smtpd_tls_wrappermode = no
95 | smtpd_tls_security_level = may
96 | smtpd_tls_eecdh_grade = ultra
97 | smtpd_tls_protocols = !SSLv2, !SSLv3
98 | smtpd_tls_auth_only = yes
99 | smtpd_tls_loglevel = 1
100 |
101 | smtpd_sasl_auth_enable = yes
102 | smtpd_sasl_type = dovecot
103 | smtpd_sasl_path = private/auth
104 | smtpd_sasl_authenticated_header = yes
105 |
106 | smtp_tls_security_level = may
107 | smtp_tls_eecdh_grade = ultra
108 | smtp_tls_cert_file = /var/lib/acme/pastespace.org/cert.pem
109 | smtp_tls_key_file = /var/lib/acme/pastespace.org/key.pem
110 | smtp_tls_session_cache_database = btree:''${queue_directory}/smtp_scache
111 | smtp_tls_loglevel = 1
112 |
113 | tls_random_source = dev:/dev/urandom
114 | tls_eecdh_strong_curve = prime256v1
115 | tls_eecdh_ultra_curve = secp384r1
116 |
117 | smtpd_relay_restrictions =
118 | permit_sasl_authenticated
119 | permit_mynetworks
120 | reject_unauth_destination
121 |
122 | smtpd_recipient_restrictions =
123 | permit_sasl_authenticated
124 | permit_mynetworks
125 | reject_unauth_destination
126 | reject_invalid_hostname
127 | reject_non_fqdn_hostname
128 | reject_non_fqdn_sender
129 | reject_non_fqdn_recipient
130 | reject_unknown_reverse_client_hostname
131 |
132 | smtpd_helo_restrictions =
133 | permit_sasl_authenticated
134 | permit_mynetworks
135 | reject_unknown_helo_hostname
136 | reject_invalid_hostname
137 | reject_unauth_pipelining
138 | reject_non_fqdn_hostname
139 |
140 | smtpd_helo_required = yes
141 |
142 | smtpd_data_restrictions =
143 | reject_unauth_pipelining
144 |
145 | smtpd_sender_restrictions =
146 | permit_sasl_authenticated
147 | permit_mynetworks
148 | reject_unknown_sender_domain
149 | reject_sender_login_mismatch
150 | reject_unauth_pipelining
151 | reject_non_fqdn_sender
152 | permit
153 |
154 | # OpenDKIM mail verification
155 | milter_default_action = accept
156 | milter_protocol = 2
157 | smtpd_milters = unix:/var/run/opendkim/opendkim.sock
158 | non_smtpd_milters = unix:/var/run/opendkim/opendkim.sock
159 | '';
160 | extraMasterConf =
161 | ''
162 | submission inet n - n - - smtpd
163 | -o syslog_name=postfix/submission
164 | -o milter_macro_daemon_name=ORIGINATING
165 | -o smtpd_tls_security_level=encrypt
166 | -o smtpd_sasl_security_options=noanonymous
167 | '';
168 | };
169 |
170 | networking.firewall =
171 | {
172 | allowedTCPPorts =
173 | [
174 | 25 # smtp
175 | 587 # smtp
176 | ];
177 | };
178 | }
179 |
--------------------------------------------------------------------------------
/server/service/radicale.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | services.radicale = {
5 | enable = true;
6 | config =
7 | ''
8 | [server]
9 | hosts = 0.0.0.0:5232
10 | #base_prefix = /calendar/
11 | #can_skip_base_prefix = True
12 |
13 | [auth]
14 | type = None
15 |
16 | [rights]
17 | type = none
18 |
19 | #[git]
20 | #committer = Radicale
21 |
22 | [logging]
23 | debug = False
24 | '';
25 | };
26 |
27 | environment.etc =
28 | {
29 | "radicale/logging".text =
30 | ''
31 | [loggers]
32 | keys = root
33 |
34 | [handlers]
35 | keys = console,file
36 |
37 | [formatters]
38 | keys = full
39 |
40 | [logger_root]
41 | level = WARNING
42 | handlers = console,file
43 |
44 | [handler_console]
45 | class = StreamHandler
46 | args = (sys.stdout,)
47 | formatter = full
48 |
49 | [handler_file]
50 | # File handler
51 | class = FileHandler
52 | args = ('/tmp/radicale',)
53 | formatter = full
54 |
55 | [formatter_full]
56 | format = %(asctime)s - %(levelname)s: %(message)s
57 | '';
58 | };
59 | }
60 |
--------------------------------------------------------------------------------
/server/service/rainloop.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }:
2 |
3 | {
4 | environment.etc =
5 | {
6 | "upgrade-rainloop" =
7 | {
8 | text =
9 | ''
10 | export PATH=${pkgs.curl}/bin:${pkgs.wget}/bin:${pkgs.gnupg}/bin:${pkgs.rsync}/bin:${pkgs.unzip}/bin:$PATH
11 | ${lib.readFile ./data/upgrade-rainloop}
12 | '';
13 | mode = "0774";
14 | };
15 | };
16 |
17 | services.cron.systemCronJobs =
18 | [
19 | "@daily root /etc/upgrade-rainloop"
20 | ];
21 | }
22 |
--------------------------------------------------------------------------------
/server/service/safepaste.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages =
5 | [
6 | pkgs.boot
7 | pkgs.nodejs
8 | pkgs.openjdk
9 | ];
10 |
11 | nixpkgs.config =
12 | {
13 | packageOverrides = pkgs: rec
14 | {
15 | safepaste = pkgs.callPackage ../pkg/safepaste.nix { };
16 | };
17 | };
18 |
19 | environment.etc."user/safepaste/run-server" =
20 | {
21 | text =
22 | ''
23 | #!/run/current-system/sw/bin/bash
24 | set -eu
25 | export PATH=${pkgs.openssl}/bin:$PATH
26 |
27 | cd /etc/user/safepaste
28 | #for p in about donate;
29 | #do
30 | # ${pkgs.safepaste}/bin/encrypt $p ${pkgs.safepaste}/share /etc/user/safepaste/paste
31 | #done
32 | ${pkgs.openjdk}/bin/java -jar ${pkgs.safepaste}/bin/safepaste-standalone.jar
33 | '';
34 | mode = "0775";
35 | };
36 |
37 | systemd.services.safepaste =
38 | {
39 | wantedBy = [ "multi-user.target" ];
40 | after = [ "network.target" ];
41 | serviceConfig =
42 | {
43 | User = "safepaste";
44 | WorkingDirectory = "/etc/user/safepaste";
45 | ExecStart = "/etc/user/safepaste/run-server";
46 | };
47 | };
48 |
49 | services.cron =
50 | {
51 | systemCronJobs =
52 | [
53 | "0 */1 * * * safepaste ${pkgs.safepaste}/bin/clean-expired /etc/user/safepaste/paste"
54 | ];
55 | };
56 |
57 |
58 | users.users.safepaste =
59 | {
60 | isNormalUser = false;
61 | home = "/etc/user/safepaste";
62 | createHome = true;
63 | };
64 | environment.etc."user/safepaste/paste/.manage-directory".text = "";
65 |
66 | system.activationScripts =
67 | {
68 | safepaste-home =
69 | {
70 | deps = [];
71 | text =
72 | ''
73 | chown -R safepaste:users /etc/user/safepaste
74 | '';
75 | };
76 | };
77 |
78 | networking.firewall.allowedTCPPorts = [ 3000 ];
79 |
80 | services.fail2ban =
81 | {
82 | jails.safepaste =
83 | ''
84 | filter = safepaste
85 | maxretry = 10
86 | findtime = 43200
87 | action = safepaste
88 | bantime = 43200
89 | enabled = true
90 | '';
91 | };
92 |
93 | environment.etc."fail2ban/filter.d/safepaste.conf".text =
94 | ''
95 | [Definition]
96 | failregex = Paste from .*
97 | '';
98 | environment.etc."fail2ban/action.d/safepaste.conf".text =
99 | ''
100 | [Definition]
101 | actionstart = touch /var/tmp/safepaste.ban
102 | chmod a+r /var/tmp/safepaste.ban
103 | actionstop = sed -i '/.*/d' /var/tmp/safepaste.ban
104 | actioncheck =
105 | actionban = ${pkgs.safepaste}/bin/ban add /var/tmp
106 | actionunban = ${pkgs.safepaste}/bin/ban remove /var/tmp
107 | '';
108 | }
109 |
--------------------------------------------------------------------------------
/server/service/spamassassin.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | services.spamassassin =
5 | {
6 | enable = true;
7 | config =
8 | ''
9 | use_bayes 1
10 | bayes_auto_learn 0
11 | '';
12 | };
13 |
14 | # Regularly update spamassassin rules and train
15 | services.cron.systemCronJobs =
16 | [
17 | "@daily root ${pkgs.spamassassin}/bin/sa-update && systemctl restart spamd"
18 | "@daily root /etc/train-spamassassin"
19 | ];
20 |
21 | # https://github.com/NixOS/nixpkgs/issues/7915#issuecomment-104882091
22 | environment.etc =
23 | {
24 | "procmailrc" =
25 | {
26 | text =
27 | ''
28 | SHELL="/bin/bash"
29 | LINEBUF=4096
30 | SENDMAIL="/run/wrappers/bin/sendmail -oi -t"
31 | DEFAULT="$HOME/Maildir/"
32 | MAILDIR="$HOME/Maildir/"
33 | DROPPRIVS="yes"
34 | VERBOSE=on
35 | LOGFILE=$HOME/.procmail.log
36 |
37 | :0fw
38 | * < 512000
39 | | ${pkgs.spamassassin}/bin/spamc
40 |
41 | :0:
42 | * ^X-Spam-Status: Yes
43 | .Spam/
44 |
45 | # Work around procmail bug: any output on stderr will cause the
46 | # "F" in "From" to be dropped. This will re-add it.
47 | :0
48 | * ^^rom[ ]
49 | {
50 | LOG="*** Dropped F off From_ header! Fixing up. "
51 |
52 | :0 fhw
53 | | sed -e '1s/^/F/'
54 | }
55 |
56 | # Apply user rules
57 | INCLUDERC=$HOME/.procmailrc
58 | '';
59 | };
60 | "train-spamassassin" =
61 | {
62 | text =
63 | ''
64 | #!/run/current-system/sw/bin/bash
65 | set -eu
66 |
67 | # TODO: Possibly run for other users
68 | ${pkgs.spamassassin}/bin/sa-learn --no-sync --spam /etc/user/jeaye/Maildir/.Spam/{cur,new}
69 | ${pkgs.spamassassin}/bin/sa-learn --no-sync --ham /etc/user/jeaye/Maildir/.Ham/{cur,new}
70 | ${pkgs.spamassassin}/bin/sa-learn --no-sync --ham /etc/user/jeaye/Maildir/.ML*/{cur,new}
71 | ${pkgs.spamassassin}/bin/sa-learn --sync
72 | '';
73 | mode = "0774";
74 | };
75 | };
76 | }
77 |
--------------------------------------------------------------------------------
/server/service/taskserver.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | services.taskserver =
5 | {
6 | enable = true;
7 | fqdn = "pastespace.org";
8 | listenHost = "::";
9 | organisations.default.users = [ "jeaye" ];
10 | };
11 |
12 | networking.firewall =
13 | {
14 | allowedTCPPorts = [ 53589 ];
15 | };
16 | }
17 |
--------------------------------------------------------------------------------
/server/service/upload.jeaye.com-tmp.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | # Uploading files via SSH is done through this user and a cron job. Better
5 | # to not expose the whole http user to SSH.
6 | users.users.http-upload =
7 | {
8 | isNormalUser = true;
9 | home = "/etc/user/http-upload";
10 | extraGroups = [ "ssh" ];
11 | openssh.authorizedKeys.keys =
12 | [
13 | "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDL8j6NtvibZpsDLWSjsPMIjUQRYHta/a8XpOJf7CQ2Aze73oFwBPaAvP1iSmpLkFCs0hp+8w0P4+eHAjp67mLgVLIvM0iESpj8YbVJACyL2Gu2J8fN63CFP3HAMEmvXGK8LSpBEErF44az0H8ZrMJPODkUYiQMX2kAgshUjtMaUqicZmWRRsiJ8bBcK2ddsWOXPzY/0j8+9KMre8YaFJve/QgmJEvVpdxt8pqklPCiMHjFI0EKRHV835mDLe/fzYK2hrTzRXw5hRpluonGce7Tg7WsVk/SmGdfysJAYOOvUwcLosK64bsg2+wIdEKG4r/Ws9FR2hqykspzx4s2o6jL jeaye@oryx"
14 | "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD0cNcqr6VeQjQqtwhxE0IcqpQo+jULXbmKsyILFoigP5chpCVKv9qYUqk5mTjiLH9TzsC17z6CIOHGIXCxZABqpAXrPoHe8kn3WXYX04l4PWRTzeuUg2SIhTv0CwUDZGCnaTVlGpLd6CCHFbxp/4fDQ4C53NdBVu0zGeuRACutF+OTpGgsdJ8JyDBn8z9+IMgxMM1K2C5geiz2arNpQJDbu/RvZBO7bD2JDUKBRkNAv986vNdpgZvrVUR3Jhg7RVPQEioVg7jF3WmOHwMX8pYlL7Nk4tLHIfOj02Gh2FsSq8aYgTsYD4+a5A4ZSmJlP1is3N6+lu/hIcITF8A8nBBNAPIKfSY1HD5XMgjObQudtCvF15LACJgtrCV7HCIcfWklra7DcQsfcuKHGMFWDFjCer7lbUIBAeV7QbNhR/H5H3vu2kTN94myStCCmjs3KzgztP/UKWEKyes7a8+7LcUwu/zHxTw/9xTFVf5YW40gMEfuS3IFJzLf5s2yK0jd91rDEtWd+/uFqLcgjFxhd75Y/JmWYgpNRfpEva+N8A3aDrJ1t/GKUtz4AhT+D1Iu0lmJOdAvjnolbruFC3LnQxnYvlifrkRv4knjW7UA2+KEKTmHhggdJoEORsgfTDcG99Kv/PXeheY/JrGeHzJvJ7RssbxlXD8WC71FKKtmJStCyQ== pwilkerson@uber.com"
15 | "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD0BDvQ+CHyLXY6HtJyRwwBq+9RdeKmRjt1TNshg34jAL1PQFoAxP4Bnk0IQLM9N2EuDwr6kLZt0l8JKozwSh4zPx9JU4nsFM5FjodgjNJRiMkJ+UUHJMtcQwEVKN5yEzJaXOWOcc8RYeQdJaj5s8LcYHeuv8DPQo55jlabLWvgJurISDvBDJ968kqmYA8r83ZI4xqvUH1E2PnYz7Yg1uPwMG8I8PFYKb6WWa4c+e5vJGiXJamqYPPcuFrEaT517JjMJSo/x2OcrXVTxQ4X39i+Qgi8W7CuuSypRh9/ozUdf8rVPk0/gI51D9Y48OLjrIh1bIKeMfTtgEhXl569EjzwHnsfOjq9HY2J4EdvrwoZB2kPwOrkDzRGCThYCuuxsmed+nZCztW0emmdjkos3vINsF+4foMrs3ucE6TDfsKJvQzB+TZ3pXmPzncKV36RBrucgJIMUOIg0Snc8o/YfuAHe57U5zHwTUKBILJNRMMSLlpbpRSmoJVYuDWA+goycBFGWDFy60BLGWNYpu3KrXnv/ggai3QdFAKtq7AzepOyP+0JtG/19z/dyG7xeUNlvBOVyuLlhxks9pQftyWkhl5+ATvG3ri/NQWnobw9D4x7NnGfbxI4/upWTuuh9QvS3ujGpPSOlPos0g3CTsfNq/664lrLDaWfE0FFAklgT7SpxQ== pwilkerson@uber.com"
16 | ];
17 | };
18 |
19 | environment.etc =
20 | {
21 | "user/http-upload/queue/.manage-directory".text = "";
22 | "user/http-upload/flush" =
23 | {
24 | text =
25 | ''
26 | #!/run/current-system/sw/bin/bash
27 | set -eu
28 |
29 | queue=/etc/user/http-upload/queue
30 |
31 | # Check if it's empty first
32 | if [ ".manage-directory" = "$(ls -A $queue)" ];
33 | then
34 | exit 0
35 | fi
36 |
37 | for file in $queue/*;
38 | do
39 | basename=$(basename "$file")
40 | mv -f "$file" /etc/user/http/upload.jeaye.com/tmp/
41 | chown -R http /etc/user/http/upload.jeaye.com/tmp/"$basename"
42 | done
43 | '';
44 | mode = "0774";
45 | };
46 | };
47 |
48 | # Clean up old files and flush queue regularly.
49 | services.cron.systemCronJobs =
50 | [
51 | "0 0 * * * http ${pkgs.findutils}/bin/find /etc/user/http/upload.jeaye.com/tmp -mtime +2 -type f -exec rm -vf {} \\;"
52 | "* * * * * root /etc/user/http-upload/flush"
53 | ];
54 | }
55 |
--------------------------------------------------------------------------------
/server/service/wordy-word.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages =
5 | [
6 | pkgs.leiningen
7 | pkgs.openjdk
8 | ];
9 |
10 | nixpkgs.config =
11 | {
12 | packageOverrides = pkgs: rec
13 | {
14 | wordy-word = pkgs.callPackage ../pkg/wordy-word.nix { };
15 | };
16 | };
17 |
18 | environment.etc."user/wordy-word/run-server" =
19 | {
20 | text =
21 | ''
22 | #!/run/current-system/sw/bin/bash
23 | set -eu
24 |
25 | ${pkgs.openjdk}/bin/java -jar ${pkgs.wordy-word}/bin/wordy-word.jar
26 | '';
27 | mode = "0775";
28 | };
29 |
30 | systemd.services.wordy-word =
31 | {
32 | wantedBy = [ "multi-user.target" ];
33 | after = [ "network.target" ];
34 | serviceConfig =
35 | {
36 | User = "wordy-word";
37 | WorkingDirectory = "/etc/user/wordy-word";
38 | ExecStart = "/etc/user/wordy-word/run-server";
39 | };
40 | };
41 |
42 | users.users.wordy-word =
43 | {
44 | isNormalUser = true;
45 | home = "/etc/user/wordy-word";
46 | createHome = true;
47 | };
48 |
49 | system.activationScripts =
50 | {
51 | wordy-word-home =
52 | {
53 | deps = [];
54 | text =
55 | ''
56 | export PATH=${pkgs.wget}/bin:${pkgs.gnutar}/bin:${pkgs.gzip}/bin:$PATH
57 | if [ ! -f /etc/user/wordy-word/unapproved-nouns ];
58 | then
59 | pushd /etc/user/wordy-word
60 | ${pkgs.wordy-word}/bin/build-word-lists
61 | popd
62 | fi
63 | chown -R wordy-word:users /etc/user/wordy-word
64 | '';
65 | };
66 | };
67 | }
68 |
--------------------------------------------------------------------------------
/server/system/environment.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | # This is a headless machine; no need for anything fancy... or so I thought.
5 | # Enabling noXlibs requires manual compilation of some large packages, like
6 | # openjdk. I'll try to disable it, to avoid massive compilations, with the
7 | # tradeoff of a larger /nix/store and attack vector.
8 | environment.noXlibs = false;
9 | fonts.fontconfig.enable = false;
10 | sound.enable = false;
11 |
12 | # Auto GC every morning
13 | nix.gc.automatic = false;
14 | services.cron.systemCronJobs = [ "0 3 * * * root /etc/admin/optimize-nix" ];
15 |
16 | environment.etc =
17 | {
18 | "admin/optimize-nix" =
19 | {
20 | text =
21 | ''
22 | #!/run/current-system/sw/bin/bash
23 | set -eu
24 |
25 | # Delete everything from this profile that isn't currently needed
26 | nix-env --delete-generations old
27 |
28 | # Delete generations older than a week
29 | nix-collect-garbage
30 | nix-collect-garbage --delete-older-than 7d
31 |
32 | # Optimize
33 | nix-store --gc --print-dead
34 | nix-store --optimise
35 | '';
36 | mode = "0774";
37 | };
38 | };
39 | }
40 |
--------------------------------------------------------------------------------
/server/system/network.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | networking =
5 | {
6 | wireless.enable = false;
7 | enableIPv6 = false;
8 |
9 | # Allow containers to have private networks
10 | nat =
11 | {
12 | enable = true;
13 | internalInterfaces = ["ve-+"];
14 | externalInterface = "ens3";
15 | };
16 | };
17 | }
18 |
--------------------------------------------------------------------------------
/server/system/security.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | security.sudo =
5 | {
6 | enable = false;
7 | wheelNeedsPassword = true;
8 | };
9 | }
10 |
--------------------------------------------------------------------------------
/server/system/user.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | system.activationScripts =
5 | {
6 | homes =
7 | {
8 | deps = [];
9 | text = (builtins.foldl'
10 | (us: u:
11 | ''
12 | ${us}
13 | ln -sf /etc/user/dotfiles/bash_profile /etc/user/${u.name}/.bash_profile
14 | ln -sf /etc/user/dotfiles/bashrc /etc/user/${u.name}/.bashrc
15 | ln -sf /etc/user/dotfiles/dir_colors /etc/user/${u.name}/.dir_colors
16 | ln -sf /etc/user/dotfiles/gitconfig /etc/user/${u.name}/.gitconfig
17 | ln -sf /etc/user/dotfiles/gitignore /etc/user/${u.name}/.gitignore
18 | ln -sf /etc/user/dotfiles/tmux.conf /etc/user/${u.name}/.tmux.conf
19 | ln -sf /etc/user/dotfiles/elinks /etc/user/${u.name}/.elinks
20 | chown -R ${u.name}:users /etc/user/${u.name}
21 | '')
22 | ""
23 | (builtins.filter (u: u.isNormalUser)
24 | (map (key: builtins.getAttr key config.users.users)
25 | (builtins.attrNames config.users.users))));
26 | };
27 | root-home =
28 | {
29 | deps = [];
30 | text =
31 | ''
32 | ln -sf /etc/user/dotfiles/bash_profile /root/.bash_profile
33 | ln -sf /etc/user/dotfiles/bashrc /root/.bashrc
34 | ln -sf /etc/user/dotfiles/dir_colors /root/.dir_colors
35 | ln -sf /etc/user/dotfiles/tmux.conf /root/.tmux.conf
36 | ln -sf /etc/user/dotfiles/tmux-nixos.conf /root/.tmux-nixos.conf
37 | '';
38 | };
39 | };
40 |
41 | # Allow useradd/groupadd imperatively
42 | users.mutableUsers = true;
43 | }
44 |
--------------------------------------------------------------------------------
/server/user/fu-er.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | users.users.fu-er =
5 | {
6 | isNormalUser = true;
7 | home = "/etc/user/fu-er";
8 | extraGroups = [ "ssh" ];
9 | };
10 |
11 | environment.etc =
12 | {
13 | "user/fu-er/.procmailrc" =
14 | {
15 | text =
16 | ''
17 | INCLUDERC=/etc/user/fu-er/.procmail/spam.rc
18 | '';
19 | };
20 | "user/fu-er/.procmail/spam.rc" =
21 | {
22 | text =
23 | ''
24 | # TrueIdentity
25 | :0:
26 | * ^From: .*e-tui\.transunion\.com.*
27 | .Trash/
28 |
29 | # Junk
30 | :0:
31 | * ^(From|Cc|To|X-Original-To): kitty@pastespace\.org
32 | .Junk/
33 | '';
34 | };
35 | };
36 | }
37 |
--------------------------------------------------------------------------------
/server/user/git.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | users.users.git =
5 | {
6 | isNormalUser = true;
7 | home = "/etc/user/git";
8 | createHome = true;
9 | extraGroups = [ "ssh" ];
10 | };
11 | users.groups.git = {};
12 |
13 | # Ensure some directories exist
14 | environment.etc."user/git/dotfiles/.manage-directory".text = "";
15 |
16 | # XXX: Manually bring in dotfiles repo
17 | system.activationScripts =
18 | {
19 | git-home =
20 | {
21 | deps = [];
22 | text =
23 | ''
24 | PATH=${pkgs.git}/bin:$PATH
25 | PATH=${pkgs.gnused}/bin:$PATH
26 |
27 | if [ ! -d /etc/user/dotfiles ];
28 | then
29 | git clone --recursive /etc/user/git/dotfiles /etc/user/dotfiles
30 | fi
31 | chgrp -R git /etc/user/dotfiles
32 | chmod -R g+w /etc/user/dotfiles
33 | '';
34 | };
35 | };
36 | }
37 |
--------------------------------------------------------------------------------
/server/user/irc.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs;
5 | [
6 | weechat
7 | aspell
8 | aspellDicts.en
9 | ];
10 |
11 | users.users.irc =
12 | {
13 | isNormalUser = true;
14 | home = "/etc/user/irc";
15 | createHome = true;
16 | extraGroups = [ "git" ];
17 | };
18 |
19 | system.activationScripts =
20 | {
21 | irc-home =
22 | {
23 | deps = [];
24 | text =
25 | ''
26 | ln -sf /etc/user/dotfiles/weechat /etc/user/irc/.weechat
27 | '';
28 | };
29 | };
30 |
31 | networking.firewall =
32 | {
33 | allowedTCPPorts =
34 | [
35 | 113 # ident
36 | ];
37 | };
38 | }
39 |
--------------------------------------------------------------------------------
/server/user/jeaye.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | let
4 | spamassassin_prefs =
5 | ''
6 | required_score 3
7 | report_safe 0
8 | score BAYES_00 -4
9 | score BAYES_05 -2
10 | score BAYES_95 6
11 | score BAYES_99 9
12 | '';
13 | in
14 | {
15 | environment.systemPackages = with pkgs;
16 | [
17 | tmux
18 | neomutt
19 | pinentry
20 | gnupg
21 | ];
22 |
23 | users.users.jeaye =
24 | {
25 | isNormalUser = true;
26 | home = "/etc/user/jeaye";
27 | extraGroups = [ "wheel" "ssh" ];
28 | };
29 |
30 | system.activationScripts =
31 | {
32 | jeaye-home =
33 | {
34 | deps = [];
35 | text =
36 | ''
37 | PATH=${pkgs.git}/bin:$PATH
38 | PATH=${pkgs.gnused}/bin:$PATH
39 |
40 | if [ ! -d /etc/user/jeaye/.vim ];
41 | then
42 | # TODO: Network IO in an activation script is bad
43 | git clone --recursive https://github.com/jeaye/vimrc.git /etc/user/jeaye/.vim
44 | ln -sf /etc/user/jeaye/.vim/vimrc /etc/user/jeaye/.vimrc
45 | fi
46 | chown -R jeaye:users /etc/user/jeaye/.vim
47 |
48 | user_prefs=/var/lib/spamassassin/user-jeaye/user_prefs
49 | rm -f "$user_prefs"
50 | echo "${spamassassin_prefs}" > "$user_prefs"
51 | chown spamd:spamd "$user_prefs"
52 | chmod 0600 "$user_prefs"
53 | '';
54 | };
55 | };
56 |
57 | environment.etc =
58 | {
59 | "user/jeaye/.procmailrc" =
60 | {
61 | text =
62 | ''
63 | INCLUDERC=/etc/user/jeaye/.procmail/list.rc
64 | INCLUDERC=/etc/user/jeaye/.procmail/work.rc
65 | INCLUDERC=/etc/user/jeaye/.procmail/admin.rc
66 | '';
67 | };
68 | "user/jeaye/.procmail/list.rc" =
69 | {
70 | text =
71 | ''
72 | # Clojure mailing list
73 | :0:
74 | * ^X-BeenThere: clojure@googlegroups\.com
75 | .ML.Clojure/
76 |
77 | # ClojureScript mailing list
78 | :0:
79 | * ^X-BeenThere: clojurescript@googlegroups\.com
80 | .ML.ClojureScript/
81 |
82 | # Clang mailing list
83 | :0:
84 | * ^X-BeenThere: cfe-(users|dev)@cs\.uiuc\.edu
85 | .ML.Clang/
86 |
87 | # ISOC++ mailing list
88 | :0:
89 | * ^X-BeenThere: std-(proposals|discussion)@isocpp\.org
90 | .ML.ISOCPP/
91 |
92 | # Slackware mailing list
93 | :0:
94 | * ^(From|Cc|To).*slackware-(security|announce)@slackware\.com
95 | .ML.Slackware/
96 |
97 | # NixOS mailing list
98 | :0:
99 | * ^X-BeenThere: nix-dev@lists\.science\.uu\.nl
100 | .ML.NixOS/
101 |
102 | # NixOS-Security mailing list
103 | :0:
104 | * ^X-BeenThere: nix-security-announce@googlegroups\.com
105 | .ML.NixOS-Sec/
106 |
107 | # Junk
108 | :0:
109 | * ^(From|Cc|To): (junk@pastespace\.org|junk@jeaye.com)|lorgonjortle.*
110 | .Junk/
111 | '';
112 | };
113 | "user/jeaye/.procmail/work.rc" =
114 | {
115 | text =
116 | ''
117 | # Furthington bucket
118 | :0:
119 | * ^(From|Cc|To).*furthington\.com
120 | .Furthington/
121 |
122 | # Hiring bucket
123 | :0:
124 | * ^(From|Cc|To).*(hiring@okletsplay.com)
125 | .LetsBet-Hiring/
126 |
127 | # LetsBet bucket
128 | :0:
129 | * ^(From|Cc|To).*(russalek13.*|.*@okletsplay.com)
130 | .LetsBet/
131 |
132 | # TinyCo bucket
133 | :0:
134 | * ^(From|Cc|To).*brooklynpacket/.*
135 | .TinyCo/
136 | '';
137 | };
138 | "user/jeaye/.procmail/admin.rc" =
139 | {
140 | text =
141 | ''
142 | # DMARC reports
143 | :0:
144 | * ^Subject: Report [dD]omain:
145 | .ML.DMARC/
146 |
147 | # Cron reports
148 | :0:
149 | * ^From: Cron Daemon
150 | .Cron/
151 | '';
152 | };
153 | };
154 | }
155 |
--------------------------------------------------------------------------------
/server/user/okletsplay.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | users.users.okletsplay =
5 | {
6 | isNormalUser = false;
7 | createHome = false;
8 | };
9 | }
10 |
--------------------------------------------------------------------------------
/server/util/acme.nix:
--------------------------------------------------------------------------------
1 | {}:
2 |
3 | {
4 | util.acme =
5 | {
6 | directory = "/var/lib/acme-unstable";
7 | plugins = [ "account_reg.json" "account_key.json" "fullchain.pem" "chain.pem" "key.pem" "cert.pem" ];
8 | post-run =
9 | ''
10 | cp -R /var/lib/acme-unstable/* /var/lib/acme/
11 | systemctl restart httpd.service ;
12 | '';
13 | };
14 | }
15 |
--------------------------------------------------------------------------------
/server/util/http.nix:
--------------------------------------------------------------------------------
1 | {}:
2 |
3 | {
4 | util.http =
5 | {
6 | # Basic config
7 | defaults =
8 | {
9 | user = "http";
10 | adminAddr = "contact@jeaye.com";
11 | logPerVirtualHost = true;
12 | multiProcessingModule = "event";
13 |
14 | extraConfig =
15 | ''
16 | AddDefaultCharset UTF-8
17 | AddCharset UTF-8 .html .htm .txt
18 |
19 | ServerTokens Prod
20 | ServerSignature Off
21 | TraceEnable off
22 |
23 | # Prefer HTTP2
24 | Protocols h2 h2c http/1.1
25 | '';
26 | };
27 |
28 | helpers =
29 | rec {
30 | sslInfo = domain: cert_domain:
31 | ''
32 |
33 | AllowOverride None
34 | Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
35 | Require method GET POST OPTIONS
36 |
37 | Alias /.well-known/ /etc/user/http/${domain}/.well-known/
38 |
39 | SSLCertificateKeyFile /var/lib/acme/${cert_domain}/key.pem
40 | SSLCertificateChainFile /var/lib/acme/${cert_domain}/chain.pem
41 | SSLCertificateFile /var/lib/acme/${cert_domain}/cert.pem
42 | SSLProtocol All -SSLv2 -SSLv3
43 | SSLCipherSuite HIGH:!aNULL:!MD5:!EXP
44 | SSLHonorCipherOrder on
45 | '';
46 | ignoreDirectory = domain:
47 | ''
48 |
49 | Options -Indexes
50 |
51 | '';
52 | withSSL = domain: cert_domain: (ignoreDirectory domain)
53 | + (sslInfo domain cert_domain);
54 | };
55 | };
56 | }
57 |
--------------------------------------------------------------------------------
/shared/configuration.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | imports =
5 | [
6 | ## System
7 | ./system/environment.nix
8 | ./system/network.nix
9 | ./system/systemd.nix
10 | ./system/security.nix
11 |
12 | ## Users
13 | ./system/user.nix
14 |
15 | ## Services
16 | ./service/time.nix
17 | ./service/locate.nix
18 | ./service/ssh.nix
19 | ];
20 | }
21 |
--------------------------------------------------------------------------------
/shared/service/locate.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | services.locate.enable = true;
5 | }
6 |
--------------------------------------------------------------------------------
/shared/service/ssh.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }:
2 |
3 | {
4 | services.openssh =
5 | {
6 | enable = true;
7 | allowSFTP = lib.mkDefault false;
8 | settings =
9 | {
10 | X11Forwarding = false;
11 | PermitRootLogin = "no";
12 | };
13 | hostKeys =
14 | [
15 | { type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; }
16 | { type = "rsa"; bits = 4096; path = "/etc/ssh/ssh_host_rsa_key"; }
17 | ];
18 | extraConfig =
19 | ''
20 | PermitEmptyPasswords no
21 |
22 | # Avoid DNS lookups.
23 | UseDNS no
24 |
25 | # Throttle to a reasonable amount for a small server.
26 | MaxStartups 5
27 | MaxSessions 5
28 | MaxAuthTries 5
29 |
30 | # Don't allow just anyone to use SSH.
31 | AllowGroups ssh
32 |
33 | # LogLevel VERBOSE logs user's key fingerprint on login.
34 | # Needed to have a clear audit track of which key was used to log in.
35 | LogLevel VERBOSE
36 |
37 | # Use kernel sandbox mechanisms where possible in unprivileged processes.
38 | UsePrivilegeSeparation sandbox
39 | '';
40 | };
41 |
42 | networking.firewall.allowedTCPPorts = lib.mkDefault [ 22 ];
43 | }
44 |
--------------------------------------------------------------------------------
/shared/service/time.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | time.timeZone = "America/Los_Angeles";
5 | services.ntp.enable = false;
6 | }
7 |
--------------------------------------------------------------------------------
/shared/system/boot.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | boot.kernelParams = [ "boot.shell_on_fail" ];
5 |
6 | boot.loader.systemd-boot.enable = true;
7 | boot.loader.efi.canTouchEfiVariables = true;
8 |
9 | # Clean up /tmp on boot
10 | boot.cleanTmpDir = true;
11 |
12 | swapDevices =
13 | [
14 | {
15 | # Nix will create this automagically
16 | device = "/swap";
17 | size = 2048;
18 | }
19 | ];
20 | }
21 |
--------------------------------------------------------------------------------
/shared/system/environment.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | i18n =
5 | {
6 | defaultLocale = "en_US.UTF-8";
7 | };
8 | console =
9 | {
10 | keyMap = "us";
11 | font = "Lat2-Terminus16";
12 | };
13 |
14 | i18n.extraLocaleSettings = {
15 | LC_ADDRESS = "en_US.UTF-8";
16 | LC_IDENTIFICATION = "en_US.UTF-8";
17 | LC_MEASUREMENT = "en_US.UTF-8";
18 | LC_MONETARY = "en_US.UTF-8";
19 | LC_NAME = "en_US.UTF-8";
20 | LC_NUMERIC = "en_US.UTF-8";
21 | LC_PAPER = "en_US.UTF-8";
22 | LC_TELEPHONE = "en_US.UTF-8";
23 | LC_TIME = "en_US.UTF-8";
24 | };
25 |
26 | programs.bash.enableCompletion = true;
27 |
28 | nix.settings.allowed-users = [ "@wheel" ];
29 | nix.optimise =
30 | {
31 | automatic = true;
32 | dates = [ "weekly" ];
33 | };
34 | nix.gc =
35 | {
36 | automatic = true;
37 | dates = "weekly";
38 | options = "--delete-older-than 7d";
39 | };
40 | }
41 |
--------------------------------------------------------------------------------
/shared/system/network.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | networking =
5 | {
6 | firewall =
7 | {
8 | enable = true;
9 | allowPing = true;
10 | };
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/shared/system/security.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | }
5 |
--------------------------------------------------------------------------------
/shared/system/systemd.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | services.journald.extraConfig =
5 | ''
6 | Storage=persist
7 | Compress=yes
8 | SystemMaxUse=128M
9 | RuntimeMaxUse=8M
10 | '';
11 | }
12 |
--------------------------------------------------------------------------------
/shared/system/user.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | # TODO: Good values here.
5 | # security.pam.loginLimits =
6 | # [
7 | # { domain = "*"; item = "nproc"; type = "soft"; value = "1024"; }
8 | # { domain = "*"; item = "nproc"; type = "hard"; value = "1024"; }
9 | # { domain = "*"; item = "maxlogins"; type = "hard"; value = "3"; }
10 | # { domain = "*"; item = "nofile"; type = "hard"; value = "1024"; }
11 | # ];
12 |
13 | # Required for SSH access.
14 | users.groups.ssh = {};
15 | }
16 |
--------------------------------------------------------------------------------
/workstation/configuration.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | # TODO:
4 | # firejail
5 |
6 | {
7 | hardware.system76.enableAll = true;
8 |
9 | imports =
10 | [
11 | ./hardware-configuration.nix # Auto-generated by nixos
12 | ../shared/configuration.nix
13 |
14 | ## More secure defaults
15 | # TODO: Can we have this?
16 | #
17 |
18 | ## System
19 | ./system/boot.nix
20 | ./system/environment.nix
21 | ./system/network.nix
22 | ./system/security.nix
23 | ./system/sound.nix
24 | ./system/usb.nix
25 |
26 | ## Global programs
27 | ./program/essential.nix
28 |
29 | ## Users
30 | ./system/user.nix
31 | ./user/jeaye.nix
32 |
33 | ## Services
34 | ./service/x11.nix
35 | ./service/virtualbox.nix
36 |
37 | # Overrides.
38 | ./service/ssh.nix
39 | ./service/docker.nix
40 | ];
41 |
42 | system.stateVersion = "23.11";
43 | }
44 |
--------------------------------------------------------------------------------
/workstation/hardware-configuration.nix:
--------------------------------------------------------------------------------
1 | # Do not modify this file! It was generated by ‘nixos-generate-config’
2 | # and may be overwritten by future invocations. Please make changes
3 | # to /etc/nixos/configuration.nix instead.
4 | { config, lib, pkgs, modulesPath, ... }:
5 |
6 | {
7 | imports =
8 | [ (modulesPath + "/installer/scan/not-detected.nix")
9 | ];
10 |
11 | boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" ];
12 | boot.initrd.kernelModules = [ ];
13 | boot.kernelModules = [ "kvm-amd" ];
14 | boot.extraModulePackages = [ ];
15 |
16 | fileSystems."/" =
17 | { device = "/dev/disk/by-uuid/f8075176-413f-467c-8686-8b54bde595eb";
18 | fsType = "ext4";
19 | };
20 |
21 | boot.initrd.luks.devices."luks-a7845599-2a15-4155-ab69-a023bf7a2034".device = "/dev/disk/by-uuid/a7845599-2a15-4155-ab69-a023bf7a2034";
22 |
23 | fileSystems."/boot" =
24 | { device = "/dev/disk/by-uuid/9345-1BA8";
25 | fsType = "vfat";
26 | };
27 |
28 | swapDevices = [ ];
29 |
30 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
31 | # (the default) this is the recommended approach. When using systemd-networkd it's
32 | # still possible to use this option, but it's recommended to use it in conjunction
33 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`.
34 | networking.useDHCP = lib.mkDefault true;
35 | # networking.interfaces.enp4s0.useDHCP = lib.mkDefault true;
36 | # networking.interfaces.enp6s0.useDHCP = lib.mkDefault true;
37 | # networking.interfaces.wlo2.useDHCP = lib.mkDefault true;
38 |
39 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
40 | hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
41 | }
42 |
--------------------------------------------------------------------------------
/workstation/program/essential.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = let pkgsUnstable = import
5 | (
6 | fetchTarball https://github.com/NixOS/nixpkgs/archive/master.tar.gz
7 | )
8 | { };
9 | in
10 | with pkgs;
11 | [
12 | ## Vim
13 | neovim
14 | tree-sitter
15 | fzf
16 | silver-searcher
17 | ripgrep
18 |
19 | ## Browsing/downloading
20 | wget
21 |
22 | ## Reading
23 | #pkgsUnstable.koodo-reader
24 |
25 | ## File formats
26 | unzip
27 | file
28 |
29 | ## Networking
30 | traceroute
31 | sshfs
32 |
33 | ## Source control
34 | git
35 | git-lfs
36 |
37 | ## Shell
38 | tmux
39 | # 0.13.0 migrated to toml
40 | pkgsUnstable.alacritty
41 | starship
42 | pcre
43 |
44 | ## Administration
45 | htop
46 | psmisc
47 | lm_sensors
48 |
49 | # Hardware
50 | uhk-agent
51 |
52 | # Nix
53 | nix-index
54 | ];
55 |
56 | hardware.keyboard.uhk.enable = true;
57 | }
58 |
--------------------------------------------------------------------------------
/workstation/service/docker.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | virtualisation.docker =
5 | {
6 | enable = true;
7 | enableNvidia = false;
8 | };
9 | }
10 |
--------------------------------------------------------------------------------
/workstation/service/ssh.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | services.openssh.allowSFTP = true;
5 | networking.firewall.allowedTCPPorts = [ 2234 ];
6 | }
7 |
--------------------------------------------------------------------------------
/workstation/service/virtualbox.nix:
--------------------------------------------------------------------------------
1 | {
2 | virtualisation.virtualbox.host.enable = true;
3 | users.extraGroups.vboxusers.members = [ "jeaye" ];
4 | }
5 |
--------------------------------------------------------------------------------
/workstation/service/x11.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | services.xserver =
5 | {
6 | enable = true;
7 | autorun = true;
8 | xkb.layout = "us";
9 | #tty = 2;
10 |
11 | windowManager =
12 | {
13 | i3 =
14 | {
15 | enable = true;
16 | extraPackages = with pkgs; [ dmenu polybar i3lock hsetroot xautolock xorg.xwininfo ];
17 | };
18 | };
19 | desktopManager =
20 | {
21 | xterm.enable = false;
22 | };
23 | displayManager =
24 | {
25 | startx.enable = true;
26 | };
27 | };
28 |
29 | nixpkgs.overlays = [
30 | (final: prev: {
31 | polybar = prev.polybar.override
32 | {
33 | pulseSupport = true;
34 | i3Support = true;
35 | };
36 | })
37 | ];
38 |
39 | fonts =
40 | {
41 | fontconfig =
42 | {
43 | enable = true;
44 | allowBitmaps = true;
45 | useEmbeddedBitmaps = true;
46 | };
47 | fontDir.enable = true;
48 | enableGhostscriptFonts = true;
49 | packages = with pkgs;
50 | [
51 | google-fonts
52 | fira-code
53 | noto-fonts
54 | noto-fonts-emoji
55 | # Some international fonts.
56 | unifont
57 | # Icons.
58 | nerdfonts
59 | font-awesome
60 | material-icons
61 | material-design-icons
62 | material-symbols
63 | siji
64 | ];
65 | };
66 |
67 | services.redshift =
68 | {
69 | enable = true;
70 | temperature.day = 5000;
71 | temperature.night = 4500;
72 | };
73 | location.latitude = 37.5778696;
74 | location.longitude = -122.34809;
75 |
76 | # i3 docs say this is required for i3blocks.
77 | environment.pathsToLink = [ "/libexec" ];
78 |
79 | environment.sessionVariables =
80 | {
81 | # Allow GTK 2.0/3.0 themes to be found.
82 | GTK_DATA_PREFIX = "/run/current-system/sw";
83 | # Allow KDE apps to work better in i3.
84 | DESKTOP_SESSION = "kde";
85 | };
86 |
87 | # Enable OpenGL
88 | hardware.opengl =
89 | {
90 | enable = true;
91 | #driSupport = true;
92 | driSupport32Bit = true;
93 | };
94 |
95 | # Load nvidia driver for Xorg and Wayland
96 | services.xserver.videoDrivers = [ "nvidia" ];
97 |
98 | hardware.nvidia =
99 | {
100 | # Modesetting is required.
101 | modesetting.enable = true;
102 |
103 | # Nvidia power management. Experimental, and can cause sleep/suspend to fail.
104 | powerManagement.enable = false;
105 | # Fine-grained power management. Turns off GPU when not in use.
106 | # Experimental and only works on modern Nvidia GPUs (Turing or newer).
107 | powerManagement.finegrained = false;
108 |
109 | # Use the NVidia open source kernel module (not to be confused with the
110 | # independent third-party "nouveau" open source driver).
111 | # Support is limited to the Turing and later architectures. Full list of
112 | # supported GPUs is at:
113 | # https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus
114 | # Only available from driver 515.43.04+
115 | # Currently alpha-quality/buggy, so false is currently the recommended setting.
116 | open = false;
117 |
118 | # Enable the Nvidia settings menu,
119 | # accessible via `nvidia-settings`.
120 | nvidiaSettings = true;
121 |
122 | # Optionally, you may need to select the appropriate driver version for your specific GPU.
123 | package = config.boot.kernelPackages.nvidiaPackages.stable;
124 | };
125 | }
126 |
--------------------------------------------------------------------------------
/workstation/system/boot.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | boot =
5 | {
6 | loader.systemd-boot.enable = true;
7 | loader.efi.canTouchEfiVariables = true;
8 | };
9 |
10 | fileSystems."/".options = [ "noatime" ];
11 | }
12 |
--------------------------------------------------------------------------------
/workstation/system/environment.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | # TODO: Remove this file and move these options elsewhere
4 | {
5 | nixpkgs.config.allowUnfree = true;
6 | nix.settings.experimental-features = [ "nix-command" "flakes" ];
7 | }
8 |
--------------------------------------------------------------------------------
/workstation/system/network.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | networking = rec
5 | {
6 | hostName = "thelio";
7 |
8 | enableIPv6 = false;
9 |
10 | networkmanager.enable = true;
11 |
12 | hosts =
13 | {
14 | "127.0.0.1" =
15 | [
16 | "${hostName}.localdomain"
17 | "${hostName}"
18 | ];
19 | };
20 | };
21 |
22 | services.mullvad-vpn.enable = true;
23 | services.mullvad-vpn.package = pkgs.mullvad-vpn;
24 | /* Required to get DNS working with mullvad.
25 | * https://discourse.nixos.org/t/connected-to-mullvadvpn-but-no-internet-connection/35803/15
26 | */
27 | networking.resolvconf.enable = false;
28 |
29 | networking.firewall.allowedTCPPorts = [
30 | 80
31 | 443
32 | 1401
33 | # Minecraft server
34 | 25565
35 | ];
36 | networking.firewall.allowedUDPPorts = [ 53 1194 1195 1196 1197 1300 1301 1302 1303 1400 ];
37 |
38 | imports =
39 | [
40 | ./network/malicious-host.nix
41 | ];
42 | }
43 |
--------------------------------------------------------------------------------
/workstation/system/network/malicious-host.nix:
--------------------------------------------------------------------------------
1 | # Originally from https://github.com/michalrus/dotfiles/blob/master/nixos-config/machines/desktop/modules/malicious-hosts.nix
2 | { config, lib, pkgs, ... }:
3 |
4 | let
5 | danPollock = pkgs.fetchurl
6 | {
7 | url = "http://someonewhocares.org/hosts/zero/hosts";
8 | # curl http://someonewhocares.org/hosts/zero/hosts | sha256sum
9 | sha256 = "dd5e4f9a4a3b08f8b8c5a45dcb363efeae0df47d8c80b232f8d91fb9c74ee99b";
10 | };
11 | in
12 | {
13 | # TODO: Hash isn't working here? Copy the whole thing in?
14 | #networking.extraHosts = builtins.readFile danPollock;
15 | }
16 |
--------------------------------------------------------------------------------
/workstation/system/security.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | security.lockKernelModules = false;
5 |
6 | programs.gnupg.agent =
7 | {
8 | enable = true;
9 | enableSSHSupport = true;
10 | };
11 |
12 | systemd.mounts =
13 | [
14 | { # Put /tmp on a protected tmpfs. This sucks up more RAM though.
15 | description = "Temporary Directory (/tmp)";
16 | what = "tmpfs";
17 | where = "/tmp";
18 | documentation =
19 | [
20 | "man:hier(7)"
21 | "https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems"
22 | ];
23 | before = ["local-fs.target" "umount.target"];
24 | after = ["swap.target"];
25 | conflicts = ["umount.target"];
26 | options = "rw,nosuid,nodev";
27 | type = "tmpfs";
28 |
29 | unitConfig =
30 | {
31 | ConditionPathIsSymbolicLink = "!/tmp";
32 | DefaultDependencies = "no";
33 | };
34 | }
35 | ];
36 | }
37 |
--------------------------------------------------------------------------------
/workstation/system/sound.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | services.pipewire.enable = false;
5 | hardware.pulseaudio.enable = true;
6 | hardware.pulseaudio.support32Bit = true;
7 | hardware.pulseaudio.package = pkgs.pulseaudioFull;
8 |
9 | # Disable beep.
10 | boot.blacklistedKernelModules = [ "snd_pcsp" "pcspkr" ];
11 | }
12 |
--------------------------------------------------------------------------------
/workstation/system/usb.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | # Enable USB auto-mounting.
5 | services.gvfs.enable = true;
6 | }
7 |
--------------------------------------------------------------------------------
/workstation/system/user.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | security.sudo =
5 | {
6 | enable = true;
7 | wheelNeedsPassword = true;
8 | };
9 |
10 | # Allow useradd/groupadd imperatively.
11 | users.mutableUsers = true;
12 | }
13 |
--------------------------------------------------------------------------------
/workstation/user/jeaye.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | users.users.jeaye =
5 | {
6 | isNormalUser = true;
7 | createHome = true;
8 | group = "users";
9 | home = "/home/jeaye";
10 | extraGroups = [ "wheel" "networkmanager" "audio" "ssh" "proc" "docker" ];
11 | };
12 |
13 | imports =
14 | [
15 | #./jeaye/home.nix
16 | ./jeaye/program.nix
17 | ./jeaye/gaming.nix
18 | ./jeaye/desktop.nix
19 | ];
20 | }
21 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/Xresources:
--------------------------------------------------------------------------------
1 | ! gruvbox
2 | ! hard contrast: *background: #1d2021
3 | URxvt*background: #282828
4 | ! soft contrast: *background: #32302f
5 | URxvt*foreground: #ebdbb2
6 | ! Black + DarkGrey
7 | URxvt*color0: #282828
8 | URxvt*color8: #928374
9 | ! DarkRed + Red
10 | URxvt*color1: #cc241d
11 | URxvt*color9: #fb4934
12 | ! DarkGreen + Green
13 | URxvt*color2: #98971a
14 | URxvt*color10: #b8bb26
15 | ! DarkYellow + Yellow
16 | URxvt*color3: #d79921
17 | URxvt*color11: #fabd2f
18 | ! DarkBlue + Blue
19 | URxvt*color4: #458588
20 | URxvt*color12: #83a598
21 | ! DarkMagenta + Magenta
22 | URxvt*color5: #b16286
23 | URxvt*color13: #d3869b
24 | ! DarkCyan + Cyan
25 | URxvt*color6: #689d6a
26 | URxvt*color14: #8ec07c
27 | ! LightGrey + White
28 | URxvt*color7: #a89984
29 | URxvt*color15: #ebdbb2
30 |
31 | ! Font
32 | URxvt*termName: rxvt-256color
33 | URxvt*utf8: 1
34 | XTerm*locale: true
35 | URxvt.font: -xos4-terminus-*-*-normal-*-28-*-*-*-*-*-*-*
36 | URxvt.boldFont: -xos4-terminus-*-*-normal-*-28-*-*-*-*-*-*-*
37 | URxvt.italicFont: -xos4-terminus-*-*-normal-*-28-*-*-*-*-*-*-*
38 | URxvt.boldItalicFont: -xos4-terminus-*-*-normal-*-28-*-*-*-*-*-*-*
39 | URxvt*letterSpace: -1
40 |
41 | URxvt.depth: 32
42 | URxvt.geometry: 90x30
43 | URxvt.loginShell: true
44 | URxvt.internalBorder: 0
45 | URxvt.lineSpace: 0
46 | Xft.dpi: 96
47 | Xft.antialias: true
48 | Xft.rgba: rgb
49 | Xft.hinting: true
50 | Xft.hintstyle: hintslight
51 |
52 | ! Scrolling
53 | URxvt*scrollBar: false
54 | ! Lots
55 | URxvt*saveLines: 64000
56 |
57 | ! Bell
58 | URxvt*urgentOnBell: true
59 |
60 | ! Links
61 | URxvt.perl-ext-common: default,matcher
62 | URxvt.url-launcher: /sbin/xdg-open
63 | URxvt.matcher.button: 1
64 | URxvt.keysym.C-Delete: perl:matcher:last
65 | URxvt.keysym.M-Delete: perl:matcher:list
66 | URxvt.colorUL: #cb4b16
67 |
68 | !! Scrolling
69 | ! Do not scroll with output
70 | URxvt*scrollTtyOutput: false
71 | ! Scroll in relation to buffer (with mouse scroll or Shift+Page Up)
72 | URxvt*scrollWithBuffer: true
73 | ! Scroll back to the bottom on keypress
74 | URxvt*scrollTtyKeypress: true
75 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/bash_profile:
--------------------------------------------------------------------------------
1 | [[ -f ~/.bashrc ]] && . ~/.bashrc
2 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/bashrc:
--------------------------------------------------------------------------------
1 | # If not running interactively, don't do anything
2 | [[ $- != *i* ]] && return
3 |
4 | # Local binaries
5 | export PATH=~/bin:~/.bin:$PATH
6 |
7 | # Bash options ------------------------------------
8 | set -o vi # Vi mode
9 | set -o noclobber # do not overwrite files
10 | shopt -s globstar # recursive globbing
11 | shopt -s cdable_vars # if cd arg is not valid, assumes its a var defining a dir
12 | shopt -s cdspell # autocorrects cd misspellings
13 | shopt -s checkwinsize # update the value of LINES and COLUMNS after each command if altered
14 | shopt -s cmdhist # save multi-line commands in history as single line
15 | shopt -s histappend # do not overwrite history
16 | shopt -s dotglob # include dotfiles in pathname expansion
17 | shopt -s expand_aliases # expand aliases
18 | shopt -s extglob # enable extended pattern-matching features
19 | shopt -s progcomp # programmable completion
20 | shopt -s hostcomplete # attempt hostname expansion when @ is at the beginning of a word
21 | shopt -s nocaseglob # pathname expansion will be treated as case-insensitive
22 |
23 | # Have a large history and clean up duplicated lines
24 | unset HISTFILESIZE
25 | HISTSIZE="1000000"
26 | HISTCONTROL=ignoreboth:erasedups
27 | export HISTSIZE
28 |
29 | # Ignore duplicate commands, simple shit, and dangerous shit
30 | export HISTIGNORE="&:ls:[bf]g:exit:clear:cl:history:su:su *:sudo *"
31 |
32 | ## 256 colors
33 | export TERM=rxvt-256color
34 | export EDITOR=nvim
35 | export GPG_TTY=$(tty)
36 | export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01;32:quote=01'
37 |
38 | ## UTF-8
39 | export LC_ALL="en_US.UTF-8"
40 | export LANG="en_US.UTF-8"
41 | export LANGUAGE="en_US.UTF-8"
42 |
43 | # fzf bindings
44 | if command -v fzf-share >/dev/null;
45 | then
46 | source "$(fzf-share)/key-bindings.bash"
47 | fi
48 |
49 | # Rust/Cargo
50 | export PATH=~/.cargo/bin:$PATH
51 |
52 | [ -f ~/.bashrc-alias ] && source ~/.bashrc-alias
53 | [ -f ~/.bashrc-less ] && source ~/.bashrc-less
54 | [ -f ~/.bashrc-prompt ] && source ~/.bashrc-prompt
55 | [ -f ~/.bashrc-secret ] && source ~/.bashrc-secret
56 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/bashrc-alias:
--------------------------------------------------------------------------------
1 | # Favor verbosity and color
2 | alias cp='cp -vi'
3 | alias mv='mv -vi'
4 | alias rm='rm -vi'
5 | alias mkdir='mkdir -pv'
6 | alias grep='grep --color=auto'
7 | alias cl='clear'
8 | alias ls='ls --color=auto'
9 | alias less='less -R'
10 | alias vim='vim -p'
11 | alias gvim='gvim -p'
12 | alias rn='react-native'
13 | alias mplayer='mpv'
14 | alias ps='ps ax | grep'
15 | alias g='git'
16 | alias fail='tail -f'
17 |
18 | # Functions
19 | function weather
20 | { curl wttr.in/${1:-Burlingame}; }
21 |
22 | function define
23 | { dict "$1" | less -R; }
24 |
25 | function irc
26 | { ssh -t jeaye@pastespace.org "tmux attach || tmux new"; }
27 |
28 | function cd
29 | {
30 | if [ $# -eq 1 ];
31 | then
32 | command cd "$1"
33 | else
34 | command cd ~
35 | fi
36 | pwd >| ~/.last-directory
37 | }
38 |
39 | function cd-last-directory
40 | {
41 | last=$(cat ~/.last-directory 2>/dev/null || echo ~)
42 | command cd "$last"
43 | }
44 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/bashrc-less:
--------------------------------------------------------------------------------
1 | # Colors
2 | default=$(tput sgr0)
3 | red=$(tput setaf 1)
4 | green=$(tput setaf 2)
5 | purple=$(tput setaf 5)
6 | orange=$(tput setaf 9)
7 |
8 | # Less colors for man pages
9 | export PAGER="less -R"
10 | # Begin blinking
11 | export LESS_TERMCAP_mb=$red
12 | # Begin bold
13 | export LESS_TERMCAP_md=$orange
14 | # End mode
15 | export LESS_TERMCAP_me=$default
16 | # End standout-mode
17 | export LESS_TERMCAP_se=$default
18 | # Begin standout-mode - info box
19 | export LESS_TERMCAP_so=$purple
20 | # End underline
21 | export LESS_TERMCAP_ue=$default
22 | # Begin underline
23 | export LESS_TERMCAP_us=$green
24 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/bashrc-prompt:
--------------------------------------------------------------------------------
1 | # Colors
2 | default=$(tput sgr0)
3 | red=$(tput setaf 1)
4 | green=$(tput setaf 2)
5 | yellow=$(tput setaf 3)
6 | blue=$(tput setaf 39)
7 | purple=$(tput setaf 5)
8 | cyan=$(tput setaf 6)
9 | orange=$(tput setaf 9)
10 |
11 | # PS1 prompt
12 | git_branch()
13 | {
14 | if git rev-parse --git-dir >/dev/null 2>&1
15 | then
16 | branch=`git symbolic-ref --short HEAD 2>/dev/null`
17 | if [ -z "$branch" ]
18 | then
19 | branch="DETACHED"
20 | color=${red}
21 | elif git diff --quiet 2>/dev/null >&2
22 | then
23 | if [ -n "`git status -s --untracked-files=no 2>/dev/null`" ]
24 | then
25 | color=${yellow}
26 | else
27 | headRev=`git rev-list --max-count=1 HEAD 2>/dev/null`
28 | upstreamBranch=`git remote 2>/dev/null`/$branch
29 | upstreamRev=`git rev-list --max-count=1 $upstreamBranch 2>/dev/null`
30 | if [ "$upstreamRev" = "$headRev" ]
31 | then
32 | color=${green}
33 | else
34 | color=${blue}
35 | fi
36 | fi
37 | else
38 | color=${red}
39 | fi
40 | else
41 | return 0
42 | fi
43 | echo "[${color}$branch${default}]"
44 | }
45 | last_error()
46 | {
47 | if [[ $? == 0 ]];
48 | then
49 | echo "(${green}✓${default})"
50 | else
51 | echo "(${red}✗${default})"
52 | fi
53 | }
54 | current_time()
55 | { date "+%H:%M:%S"; }
56 | PS1='${default}┌─$(last_error)[${cyan}\u${default}@${purple}\h${default}]─[${green}\w${default}][${orange}$(current_time)${default}]$(git_branch)${default}$(tput bel)\n└──╼ '
57 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/bin/define:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | wn $1 -over
4 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/bin/i3data:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | i3status | (read line && echo $line && read line && echo $line && while :
4 | do
5 | read line
6 | #artist=$(cmus-remote -Q | grep ' artist ' | cut -d ' ' -f3-)
7 | #song=$(cmus-remote -Q | grep title | cut -d ' ' -f3-)
8 | #music="${artist} - ${song}"
9 | music=$(mpc current -f "%artist% [/ %composer% ]/ %title%")
10 | data="[{ \"full_text\": \"${music}\" },"
11 | echo "${line/[/$data}" || exit 1
12 | done)
13 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/bin/lock:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | i3lock -e -c 002b36
4 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/bin/super-nice:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -eu
4 |
5 | echo "Setting priority for $1"
6 | sudo renice -10 $1
7 | sudo ionice -c 2 -n 0 -p $1
8 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/bin/upload:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -eu -o pipefail
4 |
5 | scp -r "$@" http-upload@upload.jeaye.com:queue/
6 |
7 | for f in "$@";
8 | do
9 | echo https://upload.jeaye.com/tmp/$(basename "$f")
10 | done
11 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/bin/youtube-dl-audio:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -eu -o pipefail
4 |
5 | #youtube-dl -x --audio-format "best" --audio-quality 0 "$1"
6 | youtube-dl -x --audio-format "best" --audio-quality 0 "$1"
7 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/config/i3/config:
--------------------------------------------------------------------------------
1 | # i3 config file (v4)
2 |
3 | set $mod Mod4
4 |
5 | # font for window titles. ISO 10646 = Unicode
6 | #font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
7 | font xft:terminus
8 |
9 | # Use Mouse+$mod to drag floating windows to their wanted position
10 | floating_modifier $mod
11 |
12 | # setup default environment
13 | bindsym $mod+Shift+e exec i3-msg 'workspace 1; exec firefox; workspace 2; exec urxvt; workspace 7; layout tabbed; exec urxvt; exec signal-desktop; workspace 8; exec discord; workspace 9; exec thunderbird; workspace 10; exec pavucontrol; nop '
14 |
15 | # start a terminal
16 | bindsym $mod+Return exec urxvt
17 | bindsym $mod+Shift+Return exec "urxvt -cd $(cat ~/.last-directory 2>/dev/null || echo ~)"
18 |
19 | # start a browser
20 | bindsym $mod+Shift+f exec firefox
21 |
22 | bindsym $mod+Shift+g exec lock
23 |
24 | for_window [class="(?i)gvim"] client.focused #000000 #000000 #000000 #000000
25 | for_window [class="plasmashell"] floating window
26 |
27 | # screenshot
28 | bindsym $mod+Shift+s exec import -window root ~/screen-shot-$(date +'%Y-%m-%d-%H-%M-%S').png
29 |
30 | # music control
31 | #bindsym XF86AudioPrev exec cmus-remote -r
32 | #bindsym XF86AudioNext exec cmus-remote -n
33 | #bindsym XF86AudioPause exec cmus-remote -u
34 | #bindsym XF86AudioMute exec cmus-remote -u
35 | #bindsym XF86AudioRaiseVolume exec cmus-remote -v +10
36 | #bindsym XF86AudioLowerVolume exec cmus-remote -v -10
37 |
38 | bindsym XF86AudioPrev exec mpc prev
39 | bindsym XF86AudioNext exec mpc next
40 | bindsym XF86AudioPause exec mpc toggle
41 | bindsym XF86AudioRaiseVolume exec mpc volume +10
42 | bindsym XF86AudioLowerVolume exec mpc volume -10
43 |
44 | # kill focused window
45 | bindsym $mod+x kill
46 |
47 | # start dmenu (a program launcher)
48 | bindsym $mod+d exec dmenu_run -nb '#282828' -nf '#928374' -sb '#282828' -sf '#d65d0e'
49 |
50 | # change focus
51 | bindsym $mod+j focus down
52 | bindsym $mod+k focus up
53 | bindsym $mod+l focus right
54 | bindsym $mod+h focus left
55 |
56 | # scratchpad
57 | bindsym $mod+o move scratchpad
58 | bindsym $mod+p scratchpad show
59 |
60 | # alternatively, you can use the cursor keys:
61 | bindsym $mod+Left focus left
62 | bindsym $mod+Down focus down
63 | bindsym $mod+Up focus up
64 | bindsym $mod+Right focus right
65 |
66 | # move focused window
67 | bindsym $mod+Shift+J move down
68 | bindsym $mod+Shift+K move up
69 | bindsym $mod+Shift+L move right
70 | bindsym $mod+Shift+H move left
71 |
72 | # alternatively, you can use the cursor keys:
73 | bindsym $mod+Shift+Left move left
74 | bindsym $mod+Shift+Down move down
75 | bindsym $mod+Shift+Up move up
76 | bindsym $mod+Shift+Right move right
77 |
78 | # split in horizontal orientation
79 | #bindsym $mod+h split h
80 |
81 | # split in vertical orientation
82 | bindsym $mod+v split v
83 |
84 | # enter fullscreen mode for the focused container
85 | bindsym $mod+f fullscreen
86 |
87 | # change container layout (stacked, tabbed, default)
88 | bindsym $mod+s layout stacking
89 | bindsym $mod+w layout tabbed
90 | bindsym $mod+e layout default
91 |
92 | # toggle tiling / floating
93 | bindsym $mod+Shift+space floating toggle
94 |
95 | # change focus between tiling / floating windows
96 | #bindsym $mod+space focus mode_toggle
97 |
98 | # focus the parent container
99 | bindsym $mod+a focus parent
100 |
101 | # switch to workspace
102 | bindsym $mod+1 workspace 1
103 | bindsym $mod+2 workspace 2
104 | bindsym $mod+3 workspace 3
105 | bindsym $mod+4 workspace 4
106 | bindsym $mod+5 workspace 5
107 | bindsym $mod+6 workspace 6
108 | bindsym $mod+7 workspace 7
109 | bindsym $mod+8 workspace 8
110 | bindsym $mod+9 workspace 9
111 | bindsym $mod+0 workspace 10
112 |
113 | # move focused container to workspace
114 | bindsym $mod+Shift+exclam move container to workspace 1
115 | bindsym $mod+Shift+at move container to workspace 2
116 | bindsym $mod+Shift+numbersign move container to workspace 3
117 | bindsym $mod+Shift+dollar move container to workspace 4
118 | bindsym $mod+Shift+percent move container to workspace 5
119 | bindsym $mod+Shift+asciicircum move container to workspace 6
120 | bindsym $mod+Shift+ampersand move container to workspace 7
121 | bindsym $mod+Shift+asterisk move container to workspace 8
122 | bindsym $mod+Shift+parenleft move container to workspace 9
123 | bindsym $mod+Shift+parenright move container to workspace 10
124 |
125 | # reload the configuration file
126 | bindsym $mod+Shift+C reload
127 | # restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
128 | bindsym $mod+Shift+R restart
129 | # exit i3 (logs you out of your X session)
130 | #bindsym $mod+Shift+E exit
131 |
132 | # resize window (you can also use the mouse for that)
133 | mode "resize" {
134 | # These bindings trigger as soon as you enter the resize mode
135 |
136 | # Pressing left will shrink the window’s width.
137 | # Pressing right will grow the window’s width.
138 | # Pressing up will shrink the window’s height.
139 | # Pressing down will grow the window’s height.
140 | bindsym k resize shrink height 10 px or 10 ppt
141 | bindsym j resize grow height 10 px or 10 ppt
142 | bindsym h resize shrink width 10 px or 10 ppt
143 | bindsym l resize grow width 10 px or 10 ppt
144 |
145 | # same bindings, but for the arrow keys
146 | bindsym 113 resize shrink width 10 px or 10 ppt
147 | bindsym 116 resize grow height 10 px or 10 ppt
148 | bindsym 111 resize shrink height 10 px or 10 ppt
149 | bindsym 114 resize grow width 10 px or 10 ppt
150 |
151 | # back to normal: Enter or Escape
152 | bindsym Return mode "default"
153 | bindsym Escape mode "default"
154 | }
155 |
156 | bindsym $mod+r mode "resize"
157 |
158 | # Window colors:
159 | # class border backgr. text indicator
160 | client.focused #222222 #79740e #ffffff #b8bb26
161 | client.focused_inactive #222222 #5f676a #ffffff #484e50
162 | client.unfocused #222222 #222222 #888888 #292d2e
163 | client.urgent #222222 #859900 #000000 #859900
164 | for_window [class="^.*"] border pixel 1
165 |
166 | # Start i3bar to display a workspace bar (plus the system information i3status
167 | # finds out, if available)
168 | bar {
169 | status_command ~/.bin/i3data
170 | position bottom
171 | workspace_buttons yes
172 | #mode hide
173 | font pango:DejaVu Sans Mono 14
174 |
175 | colors {
176 | #hsetroot -solid "#282828"
177 | background #282828
178 | statusline #928374
179 | separator #d65d0e
180 |
181 | focused_workspace #a89984 #282828 #ffffff
182 | active_workspace #222222 #d65d0e #ffffff
183 | inactive_workspace #222222 #111111 #888888
184 | urgent_workspace #2f343a #d65d0e #ffffff
185 | }
186 | }
187 |
188 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/gitconfig:
--------------------------------------------------------------------------------
1 | [user]
2 | name = jeaye
3 | email = contact@jeaye.com
4 | [color]
5 | all = true
6 | ui = true
7 | branch = auto
8 | diff = auto
9 | status = auto
10 | [color "branch"]
11 | current = yellow reverse
12 | local = yellow
13 | remote = green
14 | [color "diff"]
15 | meta = yellow bold
16 | frag = magenta bold
17 | old = red bold
18 | new = green bold
19 | [color "status"]
20 | added = green
21 | changed = red
22 | untracked = yellow
23 | [alias]
24 | po = push origin
25 | pu = push upstream
26 | c = commit
27 | cp = cherry-pick
28 | ch = checkout
29 | st = status --column -sb
30 | sup = submodule update --recursive --init
31 | d = difftool --ignore-submodules
32 | di = difftool --tool=vim_ignore_whitespace -w --ignore-submodules
33 | ds = difftool --stat --ignore-submodules
34 | ll = log --pretty=oneline --graph --abbrev-commit --decorate --topo-order
35 | dp = difftool --tool=patch --ignore-submodules --minimal -w
36 | clr = clone --recursive
37 | find = log --pickaxe-all -S
38 | fpull = "!f(){ git pull \"$1\" \"$2\" && git fat pull; };f"
39 | fpush = "!f(){ git push \"$1\" \"$2\" && git fat push; };f"
40 | reset-time = "!f(){ touch -camft $(git log --date=iso --pretty=format:%cd -1 HEAD -- \"$1\" | sed 's/-//g;s/ //;s/://;s/:/./' | cut -d' ' -f1) \"$1\"; };f"
41 | deploy = push heroku
42 | [merge]
43 | keepBackup = false
44 | tool = custom_merge
45 | renamelimit = 100000
46 | [mergetool "custom_merge"]
47 | cmd = p4merge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"
48 | keepTemporaries = false
49 | trustExitCode = false
50 | keepBackup = false
51 | [diff]
52 | tool = vim
53 | renamelimit = 100000
54 | [difftool "vim"]
55 | cmd = vim -d -R "$LOCAL" "$REMOTE"
56 | [difftool "vim_ignore_whitespace"]
57 | cmd = vim -c 'set diffopt+=iwhite' -d -R "$LOCAL" "$REMOTE"
58 | [difftool]
59 | prompt = false
60 | [push]
61 | default = simple
62 | [core]
63 | pager = less -R
64 | excludesfile = /home/jeaye/.gitignore
65 | [gist]
66 | private = yes
67 | browse = no
68 | [filter "lfs"]
69 | required = true
70 | clean = git-lfs clean -- %f
71 | smudge = git-lfs smudge -- %f
72 | process = git-lfs filter-process
73 | [commit]
74 | gpgsign = true
75 | [stash]
76 | showPatch = 1
77 | [pager]
78 | log = less
79 | show = less -R
80 | diff = less -R
81 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/gitignore:
--------------------------------------------------------------------------------
1 | # Vim
2 | *~
3 | *.swp
4 | *.swo
5 |
6 | # GDB
7 | .gdbinit
8 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/i3status.conf:
--------------------------------------------------------------------------------
1 | # i3status configuration file.
2 | # see "man i3status" for documentation.
3 |
4 | # It is important that this file is edited as UTF-8.
5 | # The following line should contain a sharp s:
6 | # ß
7 | # If the above line is not correctly displayed, fix your editor first!
8 |
9 | general {
10 | output_format = "i3bar"
11 | colors = true
12 | interval = 5
13 | }
14 |
15 | #order += "ipv6"
16 | #order += "disk /"
17 | #order += "run_watch DHCP"
18 | #order += "run_watch VPN"
19 | order += "volume master"
20 | order += "wireless wlan0"
21 | #order += "ethernet eth0"
22 | order += "cpu_temperature 0"
23 | order += "battery 0"
24 | order += "load"
25 | order += "tztime local"
26 |
27 | volume master {
28 | format = "V: %volume"
29 | device = "default"
30 | mixer = "PCM"
31 | mixer_idx = 0
32 | }
33 |
34 | wireless wlan0 {
35 | format_up = "W: (%quality at %essid) %ip"
36 | format_down = "W: down"
37 | color_bad = "#657b83"
38 | }
39 |
40 | ethernet eth0 {
41 | # if you use %speed, i3status requires root privileges
42 | format_up = "E: %ip (%speed)"
43 | format_down = "E: down"
44 | }
45 |
46 | battery 0 {
47 | format = "%status %percentage %remaining"
48 | }
49 |
50 | run_watch DHCP {
51 | pidfile = "/var/run/dhclient*.pid"
52 | }
53 |
54 | run_watch VPN {
55 | pidfile = "/var/run/vpnc/pid"
56 | }
57 |
58 | tztime local {
59 | format = "%Y-%m-%d %a %H:%M:%S"
60 | }
61 |
62 | load {
63 | format = "%1min"
64 | }
65 |
66 | disk "/" {
67 | format = "%avail"
68 | }
69 |
70 | cpu_temperature 0 {
71 | format = " ± %degrees°"
72 | path = "/sys/devices/platform/coretemp.0/hwmon/hwmon2/temp1_input"
73 | max_threshold = 95
74 | }
75 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/lein/profiles.clj:
--------------------------------------------------------------------------------
1 | {:user {:plugins [[lein-ancient "0.6.10"]
2 | [lein-pprint "1.1.1"]
3 | [cider/cider-nrepl "0.13.0"]
4 | [cljfmt "0.5.1"]
5 | [venantius/ultra "0.5.0"]
6 | [lein-localrepo "0.5.3"]]}}
7 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/mpv/mpv.conf:
--------------------------------------------------------------------------------
1 | vo=opengl-hq
2 | sub-codepage=utf8
3 | softvol-max=300
4 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/tmux.conf:
--------------------------------------------------------------------------------
1 | ## 256 colors, please
2 | set -g default-terminal "screen-256color"
3 |
4 | ## Mouse scrolling
5 | #set -g mode-mouse on
6 |
7 | ## Vim
8 | set-window-option -g mode-keys vi
9 | bind-key -t vi-copy 'v' begin-selection
10 | bind-key -t vi-copy 'y' copy-selection
11 | bind P paste-buffer
12 |
13 | #### COLOR (Solarized dark)
14 |
15 | # default statusbar colors
16 | set-option -g status-bg black #base02
17 | set-option -g status-fg yellow #yellow
18 | set-option -g status-attr default
19 |
20 | # default window title colors
21 | set-window-option -g window-status-fg brightblue #base0
22 | set-window-option -g window-status-bg default
23 | #set-window-option -g window-status-attr dim
24 |
25 | # active window title colors
26 | set-window-option -g window-status-current-fg brightred #orange
27 | set-window-option -g window-status-current-bg default
28 | #set-window-option -g window-status-current-attr bright
29 |
30 | # pane border
31 | set-option -g pane-border-fg black #base02
32 | set-option -g pane-active-border-fg brightgreen #base01
33 |
34 | # message text
35 | set-option -g message-bg black #base02
36 | set-option -g message-fg brightred #orange
37 |
38 | # pane number display
39 | set-option -g display-panes-active-colour blue #blue
40 | set-option -g display-panes-colour brightred #orange
41 |
42 | # clock
43 | set-window-option -g clock-mode-colour green #green
44 |
45 | # time to recognize esc
46 | set -sg escape-time 0
47 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/data/dotfiles/xinitrc:
--------------------------------------------------------------------------------
1 | # Disable bell.
2 | xset -b
3 |
4 | # Acknowledge some more X settings.
5 | xrdb -merge ~/.Xresources
6 |
7 | # Nice background color.
8 | hsetroot -solid "#282828"
9 |
10 | # Disable laptop monitor.
11 | if [[ $(xrandr | grep "HDMI-0 connected") ]];
12 | then
13 | xrandr --output LVDS --off
14 | xrandr --output DP-0 --off
15 | xrandr --output HDMI-0 --dpi 96
16 | fi
17 |
18 | # Set keyboard layout; toggle with alt + shift.
19 | #setxkbmap -layout us,dvp -option grp:alt_shift_toggle
20 |
21 | # Lock the screen, if it's idle.
22 | xautolock -time 10 -locker "~/.bin/lock" -secure &
23 |
24 | # Remove blue light at night
25 | redshift &
26 |
27 | # Skype uses the GNOME keyring
28 | #eval $(/usr/bin/gnome-keyring-daemon --start --components=pkcs11,secrets,ssh)
29 | #export SSH_AUTH_SOCK
30 |
31 | mpd &
32 |
33 | # The X session dies when i3 exits.
34 | exec i3
35 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/desktop.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, expr, buildVM, ... }:
2 |
3 | let
4 | iconTheme = pkgs.breeze-icons.out;
5 | themeEnv =
6 | ''
7 | # GTK3: add /etc/xdg/gtk-3.0 to search path for settings.ini
8 | # We use /etc/xdg/gtk-3.0/settings.ini to set the icon and theme name for GTK 3
9 | export XDG_CONFIG_DIRS="/etc/xdg:$XDG_CONFIG_DIRS"
10 |
11 | # GTK2 theme + icon theme
12 | export GTK2_RC_FILES=${pkgs.writeText "iconrc" ''gtk-icon-theme-name="breeze"''}:${pkgs.breeze-gtk}/share/themes/Breeze/gtk-2.0/gtkrc:$GTK2_RC_FILES
13 |
14 | # SVG loader for pixbuf (needed for GTK svg icon themes)
15 | export GDK_PIXBUF_MODULE_FILE=$(echo ${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/*/loaders.cache)
16 |
17 | # QT5: convince it to use our preferred style
18 | export QT_STYLE_OVERRIDE=kvantum
19 | '';
20 | in
21 | {
22 |
23 | environment.extraInit =
24 | ''
25 | ${themeEnv}
26 |
27 | # These are the defaults, but some applications are buggy so we set them
28 | # here anyway.
29 | export XDG_CONFIG_HOME=$HOME/.config
30 | export XDG_DATA_HOME=$HOME/.local/share
31 | export XDG_CACHE_HOME=$HOME/.cache
32 | '';
33 |
34 | # QT4/5 global theme
35 | environment.etc."xdg/Trolltech.conf" =
36 | {
37 | text =
38 | ''
39 | [Qt]
40 | style=Breeze
41 | '';
42 | mode = "444";
43 | };
44 |
45 | # GTK3 global theme (widget and icon theme)
46 | environment.etc."xdg/gtk-3.0/settings.ini" =
47 | {
48 | text =
49 | ''
50 | [Settings]
51 | gtk-icon-theme-name=breeze
52 | gtk-theme-name=Breeze-gtk
53 | '';
54 | mode = "444";
55 | };
56 |
57 | users.users.jeaye =
58 | {
59 | packages = with pkgs;
60 | [
61 | redshift
62 | imagemagick
63 | flameshot
64 | xfce.thunar
65 | # Needed for thumbnails in pcmanfm
66 | xfce.tumbler
67 | # Allows pcmanfm to recognize different file types
68 | shared-mime-info
69 |
70 | # Qt theme
71 | breeze-qt5
72 | breeze-gtk
73 |
74 | # Icons (Main)
75 | iconTheme
76 |
77 | # Icons (Fallback)
78 | gnome.adwaita-icon-theme
79 |
80 | # Qt Style tooling
81 | libsForQt5.qtstyleplugin-kvantum
82 | libsForQt5.qt5ct
83 | themechanger
84 | ];
85 | };
86 |
87 | nixpkgs.config.qt5 =
88 | {
89 | enable = true;
90 | platformTheme = "qt5ct";
91 | };
92 | environment.variables.QT_QPA_PLATFORMTHEME = "qt5ct";
93 |
94 | # Make applications find files in /share
95 | environment.pathsToLink = [ "/share" ];
96 | }
97 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/gaming.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }:
2 |
3 | {
4 | #users.users.jeaye =
5 | #{
6 | # packages = with pkgs;
7 | # [
8 | # steam
9 | # ];
10 | #};
11 | programs.steam =
12 | {
13 | enable = true;
14 | # TODO: Enable once this is live.
15 | #protontricks.enable = true;
16 | };
17 |
18 | # Needed for Rocket League.
19 | nixpkgs.config.permittedInsecurePackages =
20 | [
21 | "openssl-1.1.1w"
22 | ];
23 | nixpkgs.overlays = [
24 | (final: prev: {
25 | steam = prev.steam.override ({ extraPkgs ? pkgs': [], ... }: {
26 | extraPkgs = pkgs': (extraPkgs pkgs') ++ (with pkgs'; [
27 | openssl_1_1
28 | protontricks
29 | ]);
30 | });
31 | })
32 | ];
33 |
34 | programs.gamemode.enable = true;
35 | }
36 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/home.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }:
2 |
3 | let
4 | # TODO: Use readDir + map to get these automatically.
5 | dotfiles =
6 | [
7 | "bash_profile" "bashrc" "bashrc-alias" "bashrc-less" "bashrc-prompt"
8 | "config/i3"
9 | "i3status.conf"
10 | "gitconfig"
11 | "gitignore"
12 | "xinitrc" "Xresources"
13 | "lein/profiles.clj"
14 | "mpv/mpv.conf"
15 | "tmux.conf"
16 | "bin"
17 | ];
18 | make-dotfile = file:
19 | {
20 | source = ./data/dotfiles + "/${file}";
21 | target = "user/jeaye/.${file}";
22 | };
23 | in
24 | {
25 | nixpkgs.config.packageOverrides = pkgs:
26 | {
27 | jeaye-vimrc = pkgs.callPackage ./pkg/vimrc.nix { };
28 | };
29 |
30 | # TODO: Neovim links
31 | #environment.etc =
32 | #[
33 | # ## Vim
34 | # {
35 | # source = pkgs.jeaye-vimrc + "/layer";
36 | # target = "user/jeaye/.vim/layer";
37 | # }
38 | # {
39 | # source = pkgs.jeaye-vimrc + "/build";
40 | # target = "user/jeaye/.vim/build";
41 | # }
42 | # {
43 | # source = pkgs.jeaye-vimrc + "/vimrc";
44 | # target = "user/jeaye/.vimrc";
45 | # }
46 | # ## X
47 | # {
48 | # source = ./data/dotfiles/xinitrc;
49 | # target = "user/jeaye/.xsession";
50 | # }
51 | #] ++ (map make-dotfile dotfiles);
52 |
53 | system.activationScripts =
54 | {
55 | # The permissions of ~/.vim need to be fudged, since it was made by Nix.
56 | jeaye-vimrc =
57 | {
58 | deps = [];
59 | text =
60 | ''
61 | vim_dirs=$(echo /etc/user/jeaye/.vim/{autoload,plugged})
62 | mkdir -p $vim_dirs
63 | chown -R jeaye:users $vim_dirs
64 | '';
65 | };
66 |
67 | # More fudging to account for environment.etc creations.
68 | jeaye-dotfiles =
69 | {
70 | deps = [];
71 | text =
72 | ''
73 | dotfile_dirs=$(echo /etc/user/jeaye/.{config,lein})
74 | mkdir -p $dotfile_dirs
75 | chown -R jeaye:users $dotfile_dirs
76 | '';
77 | };
78 | };
79 | }
80 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/pkg/vimrc.nix:
--------------------------------------------------------------------------------
1 | { stdenv, fetchgit }:
2 |
3 | stdenv.mkDerivation rec
4 | {
5 | name = "jeaye-vimrc";
6 | src = fetchgit
7 | {
8 | url = "https://github.com/jeaye/vimrc.git";
9 | deepClone = true;
10 | rev = "c718665";
11 | sha256 = "052hy2shkldqnkgr9vijadrwns5skgplf5027hrd5avp7vw65z42";
12 | };
13 | installPhase =
14 | ''
15 | mkdir -p $out
16 | cp -r $src/* $out/
17 | '';
18 | }
19 |
--------------------------------------------------------------------------------
/workstation/user/jeaye/program.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }:
2 |
3 | let pkgsUnstable = import
4 | (
5 | fetchTarball https://github.com/NixOS/nixpkgs/archive/master.tar.gz
6 | )
7 | { };
8 | in
9 | {
10 | users.users.jeaye =
11 | {
12 | packages = with pkgs;
13 | [
14 | ## Security
15 | pinentry
16 | gnupg
17 | keepassxc
18 |
19 | ## Editing
20 | # Noice requires nvim >=0.11
21 | pkgsUnstable.neovim
22 | fzf
23 | xclip
24 | flameshot
25 |
26 | ## Browsing
27 | firefox
28 | chromium
29 |
30 | ## Calendar
31 | thunderbird
32 |
33 | ## Media
34 | clementine
35 | mpv
36 | pavucontrol
37 | transmission_4-gtk
38 | pkgsUnstable.qbittorrent
39 | # For querying the currently playing media (MPRIS).
40 | playerctl
41 |
42 | ## Chat
43 | pkgsUnstable.signal-desktop
44 |
45 | ## Dictionary
46 | dict
47 | dictdDBs.wordnet
48 |
49 | ## Development
50 | man-pages
51 | man-pages-posix
52 | # For debugging nix builds with breakpointHook
53 | cntr
54 | distrobox
55 | # For distrobox X sharing, needed for clipboard sharing
56 | xorg.xhost
57 | pinentry-curses
58 | clojure
59 | clojure-lsp
60 | rlwrap
61 | leiningen
62 | tree
63 | clang
64 | # clangd
65 | clang-tools
66 | cmake
67 | ninja
68 | gnumake
69 | mdbook
70 | asciinema
71 | # p4merge
72 | p4v
73 |
74 | ## Art
75 | inkscape
76 | gimp
77 | blender
78 | ];
79 | };
80 |
81 | nixpkgs.overlays = [
82 | (self: super: {
83 | mpv = super.mpv.override {
84 | scripts = [ self.mpvScripts.mpris ];
85 | };
86 | })
87 | ];
88 |
89 | #nixpkgs.config.packageOverrides = self : rec {
90 | # blender = self.blender.override {
91 | # cudaSupport = true;
92 | # };
93 | #};
94 |
95 | documentation.dev.enable = true;
96 | }
97 |
--------------------------------------------------------------------------------