├── .github
└── FUNDING.yml
├── LICENSE
├── README.md
├── configuration-common.nix
├── configuration.nix
├── hardware-configuration.nix
├── machines
├── boo.nix
├── felicity.nix
├── huckandco.nix
└── nixos.nix
├── pkgs
├── bash
│ └── config.nix
├── duosec
│ └── default.nix
├── emacs
│ └── config.nix
├── gist
│ └── config.nix
├── steam
│ └── chrootenv.nix
├── tinc
│ └── default.nix
├── vim
│ └── config.nix
└── zsh
│ └── config.nix
├── profiles
├── android.nix
├── audio.nix
├── bluetooth.nix
├── cuda.nix
├── default.nix
├── desktop.nix
├── development.nix
├── docker.nix
├── dotnet.nix
├── drawing.nix
├── email.nix
├── games.nix
├── graphics.nix
├── haskell.nix
├── homeautomation.nix
├── kernel.nix
├── latex.nix
├── livecoding.nix
├── maclaptop.nix
├── mathematics.nix
├── netjail.nix
├── networking.nix
├── powermanagement.nix
├── printing.nix
├── redshift.nix
├── ruby.nix
├── rust.nix
├── steam.nix
└── virtualization.nix
├── roles
├── btsync.nix
├── gitlab-runner.nix
└── taskwarrior.nix
├── secrets.nix
├── services
├── default.nix
├── duosec.nix
├── fail2ban.nix
├── fstrim.nix
├── mosh.nix
├── ntp.nix
├── ssh-phone-home.nix
├── sshd.nix
├── tinc.nix
└── xrdp.nix
└── users
└── ghuntley.nix
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: ghuntley
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Geoffrey Huntley
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # dotfiles-nixos
2 | source drop as reference for others on how to setup nixos and share configs between multiple machines. If you find this helpful then you may also like [my notes on installing NixOS](http://ghuntley.com/notes/hetzner) on a Hetzner bare metal server with ZFS encryption (via LUKS) manually without any form of automation (ie nixops or terraform).
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/configuration-common.nix:
--------------------------------------------------------------------------------
1 | # Most of the configuration is in here. This configuration is common to both
2 | # conventional NixOS installs (see nixos-install) and NixOS installed by
3 | # Nixops. For configuration specific to conventional installs and Nixops
4 | # installs, see ./configuration.nix and ./nixops.nix respectively.
5 |
6 | { config, lib, pkgs, ... }:
7 | with lib;
8 |
9 | let secrets = import ./secrets.nix;
10 | in
11 | rec {
12 | imports = [
13 | # Import default packages.
14 | ./profiles/default.nix
15 |
16 | # Import default services.
17 | ./services/default.nix
18 |
19 | # Create user accounts
20 | ./users/ghuntley.nix
21 | ./users/mgmt.nix
22 | ];
23 |
24 | # Allow proprietary software (such as the NVIDIA drivers).
25 | nixpkgs.config.allowUnfree = true;
26 |
27 | boot = {
28 | # See console messages during early boot.
29 | initrd.kernelModules = [ "fbcon" ];
30 |
31 | # Disable console blanking after being idle.
32 | kernelParams = [ "consoleblank=0" ];
33 |
34 | # Clean /tmp on boot
35 | cleanTmpDir = true;
36 |
37 |
38 | };
39 |
40 | # /etc/hosts
41 | networking.extraHosts = secrets.extraHosts;
42 |
43 | # Google nameservers
44 | networking.nameservers = [
45 | "8.8.8.8"
46 | "8.8.4.4"
47 | ];
48 |
49 | # Select internationalisation properties.
50 | i18n = {
51 | consoleFont = "Lat2-Terminus16";
52 | consoleKeyMap = "us";
53 | defaultLocale = "en_US.UTF-8";
54 | };
55 |
56 | # Set the timezone.
57 | time.timeZone = "Australia/Sydney";
58 |
59 | # automatic updates every day
60 | system.autoUpgrade.enable = true;
61 |
62 | # automatic gc
63 | nix.gc.automatic = true;
64 | nix.gc.dates = "weekly";
65 | nix.gc.options = "--delete-older-than 30d";
66 |
67 | # FIXME: wpa_supplicant expects the wpa_supplicant.conf file to be in a read/write filesystem. This is a problem.
68 | # # Configure wireless networks
69 | # wpa_supplicant = '' # FIXME: does this name have potential for conflict? must investigate
70 | # ln -fs ${./private/etc/wpa_supplicant.conf} /etc/wpa_supplicant.conf
71 | # '';
72 | # };
73 |
74 | # Disable displaying the NixOS manual in a virtual console.
75 | services.nixosManual.showManual = false;
76 |
77 | # Disable the infamous systemd screen/tmux killer
78 | services.logind.extraConfig = ''
79 | KillUserProcesses=no
80 | '';
81 |
82 | # Increase the amount of inotify watchers
83 | # Note that inotify watches consume 1kB on 64-bit machines.
84 | boot.kernel.sysctl = {
85 | "fs.inotify.max_user_watches" = 1048576; # default: 8192
86 | "fs.inotify.max_user_instances" = 1024; # default: 128
87 | "fs.inotify.max_queued_events" = 32768; # default: 16384
88 | };
89 |
90 |
91 | # Locate will update its database everyday at lunch time
92 | services.locate.enable = true;
93 | services.locate.interval = "00 12 * * *";
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/configuration.nix:
--------------------------------------------------------------------------------
1 | # Edit this configuration file to define what should be installed on
2 | # your system. Help is available in the configuration.nix(5) man page
3 | # and in the NixOS manual (accessible by running ‘nixos-help’).
4 |
5 | { config, pkgs, ... }:
6 |
7 | {
8 | imports =
9 | [ # Include the results of the hardware scan.
10 | ./hardware-configuration.nix
11 | #./services/tinc.nix
12 | ./configuration-common.nix
13 | ./machines/boo.nix
14 | ];
15 |
16 | # Use the systemd-boot EFI boot loader.
17 | boot.loader.systemd-boot.enable = true;
18 | boot.loader.efi.canTouchEfiVariables = true;
19 |
20 |
21 | # This value determines the NixOS release with which your system is to be
22 | # compatible, in order to avoid breaking some software such as database
23 | # servers. You should change this only after NixOS release notes say you
24 | # should.
25 | system.stateVersion = "17.09"; # Did you read the comment?
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/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, ... }:
5 |
6 | {
7 | imports =
8 | [
9 | ];
10 |
11 | boot.initrd.availableKernelModules = [ "uhci_hcd" "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
12 | boot.kernelModules = [ "kvm-intel" "wl" ];
13 | boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];
14 |
15 | fileSystems."/" =
16 | { device = "/dev/disk/by-uuid/3220dac3-d696-4ca4-b022-6cd3cfcee918";
17 | fsType = "ext4";
18 | };
19 |
20 | fileSystems."/boot" =
21 | { device = "/dev/disk/by-uuid/F276-9AC1";
22 | fsType = "vfat";
23 | };
24 |
25 | swapDevices =
26 | [ { device = "/dev/disk/by-uuid/2a8a105a-e0f5-4357-a06b-b512e2b4b0bf"; }
27 | ];
28 |
29 | nix.maxJobs = lib.mkDefault 4;
30 | powerManagement.cpuFreqGovernor = "powersave";
31 | }
32 |
--------------------------------------------------------------------------------
/machines/boo.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | imports =
5 | [
6 | ../profiles/android.nix
7 | ../profiles/audio.nix
8 | #../profiles/bluetooth.nix
9 | ../profiles/desktop.nix
10 | ../profiles/development.nix
11 | #../profiles/docker.nix
12 | ../profiles/dotnet.nix
13 | ../profiles/drawing.nix
14 | ../profiles/email.nix
15 | ../profiles/games.nix
16 | ../profiles/graphics.nix
17 | ../profiles/homeautomation.nix
18 | ../profiles/latex.nix
19 | ../profiles/livecoding.nix
20 | ../profiles/maclaptop.nix
21 | ../profiles/mathematics.nix
22 | ../profiles/networking.nix
23 | ../profiles/powermanagement.nix
24 | ../profiles/printing.nix
25 | ../profiles/redshift.nix
26 | ../profiles/rust.nix
27 | ../profiles/ruby.nix
28 | ../profiles/steam.nix
29 | ../profiles/virtualization.nix
30 |
31 | ../roles/btsync.nix
32 | # Experimental
33 | ];
34 |
35 | # required for 2011 macbook air broadcom drivers
36 | nixpkgs.config.allowUnfree = true;
37 |
38 | # networking.firewall.enable = false;
39 | # networking.firewall.allowPing = true;
40 | # Set a static IP when I didn't want to set up dhcp
41 | # networking.defaultGateway = "192.168.0.1";
42 | # networking.interfaces.enp3s0 = {
43 | # ipAddress = "192.168.0.42";
44 | # prefixLength = 24;
45 | # };
46 |
47 | # Speed up development at the cost of possible build race conditions
48 | nix.buildCores = 4;
49 |
50 | # Use the systemd-boot EFI boot loader.
51 | boot.loader.systemd-boot.enable = true;
52 | boot.loader.efi.canTouchEfiVariables = true;
53 |
54 | boot.initrd.luks.devices = [
55 | {
56 | name = "root"; device = "/dev/sda2"; preLVM = true;
57 | }
58 | ];
59 |
60 | boot.extraModprobeConfig = ''
61 | options resume=/dev/rootvg/swap
62 | '';
63 |
64 |
65 | networking.hostName = "boo";
66 |
67 | services.btsync.enable = false;
68 | services.btsync.deviceName = "boo";
69 |
70 | networking.networkmanager.enable = true;
71 |
72 | powerManagement.enable = true;
73 |
74 | hardware.facetimehd.enable = true;
75 | #hardware.bluetooth.enable = true;
76 |
77 | hardware.opengl.extraPackages = [ pkgs.vaapiIntel ];
78 |
79 | }
80 |
81 |
--------------------------------------------------------------------------------
/machines/felicity.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | imports =
5 | [
6 | ../profiles/android.nix
7 | ../profiles/audio.nix
8 | ../profiles/desktop.nix
9 | ../profiles/development.nix
10 | ../profiles/docker.nix
11 | ../profiles/drawing.nix
12 | ../profiles/email.nix
13 | ../profiles/games.nix
14 | ../profiles/graphics.nix
15 | ../profiles/networking.nix
16 | ../profiles/laptop.nix
17 | ../profiles/mathematics.nix
18 | ../profiles/printing.nix
19 | ../profiles/redshift.nix
20 | ../profiles/steam.nix
21 | ../profiles/virtualization.nix
22 |
23 | # Experimental
24 | ];
25 |
26 | # networking.firewall.enable = false;
27 | networking.firewall.allowPing = true;
28 |
29 | # Set a static IP when I didn't want to set up dhcp
30 | # networking.defaultGateway = "192.168.0.1";
31 | # networking.interfaces.enp3s0 = {
32 | # ipAddress = "192.168.0.42";
33 | # prefixLength = 24;
34 | # };
35 |
36 | hardware.opengl.driSupport32Bit = true;
37 |
38 | # # Use the GRUB 2 boot loader.
39 | # boot.loader.grub.enable = true;
40 | # boot.loader.grub.version = 2;
41 | # # Define on which hard drive you want to install Grub.
42 | # boot.loader.grub.device = "/dev/sda";
43 |
44 | # Use the efi boot loader.
45 | boot.loader.systemd-boot.enable = true;
46 | boot.loader.efi.canTouchEfiVariables = true;
47 |
48 | # Speed up development at the cost of possible build race conditions
49 | nix.buildCores = 8;
50 |
51 | # Generated by nvidia-settings.
52 | services.xserver = {
53 |
54 | # Use the NVIDIA graphics drivers.
55 | videoDrivers = [ "nvidia" ];
56 |
57 | # serverLayoutSection = ''
58 | # Option "Xinerama" "0"
59 | # '';
60 | #
61 | # monitorSection = ''
62 | # # HorizSync source: edid, VertRefresh source: edid
63 | # VendorName "Unknown"
64 | # ModelName "Ancor Communications Inc VE228"
65 | # HorizSync 30.0 - 83.0
66 | # VertRefresh 50.0 - 76.0
67 | # Option "DPMS"
68 | # '';
69 | #
70 | # deviceSection = ''
71 | # Driver "nvidia"
72 | # VendorName "NVIDIA Corporation"
73 | # BoardName "GeForce GTX 670"
74 | # '';
75 | #
76 | # screenSection = ''
77 | # DefaultDepth 24
78 | # Option "Stereo" "0"
79 | # Option "metamodes" "DVI-I-1: nvidia-auto-select +0+0 {rotation=left}, DP-0: nvidia-auto-select +1080+0 {rotation=left}, DVI-D-0: nvidia-auto-select +2160+0 {rotation=left}; DVI-I-1: nvidia-auto-select +0+0 {rotation=left}; DVI-I-1: 1680x1050 +0+0 {rotation=left}; DVI-I-1: 1600x1200 +0+0 {rotation=left}; DVI-I-1: 1440x900 +0+0 {rotation=left}; DVI-I-1: 1280x1024 +0+0 {rotation=left}; DVI-I-1: 1280x1024_60 +0+0 {rotation=left}; DVI-I-1: 1280x960 +0+0 {rotation=left}; DVI-I-1: 1152x864 +0+0 {rotation=left}; DVI-I-1: 1024x768 +0+0 {rotation=left}; DVI-I-1: 1024x768_70 +0+0 {rotation=left}; DVI-I-1: 1024x768_60 +0+0 {rotation=left}; DVI-I-1: 800x600 +0+0 {rotation=left}; DVI-I-1: 800x600_72 +0+0 {rotation=left}; DVI-I-1: 800x600_60 +0+0 {rotation=left}; DVI-I-1: 800x600_56 +0+0 {rotation=left}; DVI-I-1: 640x480 +0+0 {rotation=left}; DVI-I-1: 640x480_72 +0+0 {rotation=left}; DVI-I-1: 640x480_60 +0+0 {rotation=left}"
80 | # Option "SLI" "Off"
81 | # Option "MultiGPU" "Off"
82 | # Option "BaseMosaic" "off"
83 | # SubSection "Display"
84 | # Depth 24
85 | # EndSubSection
86 | # '';
87 | };
88 | }
89 |
--------------------------------------------------------------------------------
/machines/huckandco.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | imports =
5 | [
6 | ../profiles/desktop.nix
7 | ../profiles/docker.nix
8 | ../profiles/email.nix
9 | ../profiles/virtualization.nix
10 |
11 | ../roles/gitlab-runner.nix
12 |
13 | # Experimental
14 | ];
15 |
16 | services.tinc.networks."darknet".name = "yeahnah";
17 |
18 | services.openssh = {
19 | listenAddresses = [
20 | { addr = "yeahnah"; port = 22; }
21 | { addr = "yeahnah"; port = 22; }
22 | ];
23 | };
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/machines/nixos.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | imports =
5 | [
6 | ../profiles/desktop.nix
7 | ];
8 |
9 | # Use the GRUB 2 boot loader.
10 | boot.loader.grub.enable = true;
11 | boot.loader.grub.version = 2;
12 |
13 | # Define on which hard drive you want to install Grub.
14 | #boot.loader.grub.device = "/dev/sda";
15 | }
16 |
--------------------------------------------------------------------------------
/pkgs/bash/config.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | programs.bash.enableCompletion = true;
5 |
6 | # Show git info in bash prompt and display a colorful hostname if using ssh.
7 | programs.bash.promptInit = ''
8 | export GIT_PS1_SHOWDIRTYSTATE=1
9 | source ${pkgs.gitAndTools.gitFull}/share/git/contrib/completion/git-prompt.sh
10 | __prompt_color="1;32m"
11 | # Alternate color for hostname if the generated color clashes with prompt color
12 | __alternate_color="1;33m"
13 | __hostnamecolor="$__prompt_color"
14 | # If logged in with ssh, pick a color derived from hostname
15 | if [ -n "$SSH_CLIENT" ]; then
16 | __hostnamecolor="1;$(${pkgs.nettools}/bin/hostname | od | tr ' ' '\n' | ${pkgs.gawk}/bin/awk '{total = total + $1}END{print 30 + (total % 6)}')m"
17 | # Fixup color clash
18 | if [ "$__hostnamecolor" = "$__prompt_color" ]; then
19 | __hostnamecolor="$__alternate_color"
20 | fi
21 | fi
22 | __red="1;31m"
23 | PS1='\n$(ret=$?; test $ret -ne 0 && printf "\[\e[$__red\]$ret\[\e[0m\] ")\[\e[$__prompt_color\]\u@\[\e[$__hostnamecolor\]\h \[\e[$__prompt_color\]\w$(__git_ps1 " [git:%s]")\[\e[0m\]\n$ '
24 | '';
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/pkgs/duosec/default.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | with lib;
4 |
5 | let
6 | cfg = config.security.duosec;
7 |
8 | boolToStr = b: if b then "yes" else "no";
9 |
10 | configFile = ''
11 | [duo]
12 | ikey=${cfg.ikey}
13 | skey=${cfg.skey}
14 | host=${cfg.host}
15 | ${optionalString (cfg.group != "") ("group="+cfg.group)}
16 | failmode=${cfg.failmode}
17 | pushinfo=${boolToStr cfg.pushinfo}
18 | autopush=${boolToStr cfg.autopush}
19 | motd=${boolToStr cfg.motd}
20 | prompts=${toString cfg.prompts}
21 | accept_env_factor=${boolToStr cfg.acceptEnvFactor}
22 | fallback_local_ip=${boolToStr cfg.fallbackLocalIP}
23 | '';
24 |
25 | loginCfgFile = optional cfg.ssh.enable
26 | { source = pkgs.writeText "login_duo.conf" configFile;
27 | mode = "0600";
28 | user = "sshd";
29 | target = "duo/login_duo.conf";
30 | };
31 |
32 | pamCfgFile = optional cfg.pam.enable
33 | { source = pkgs.writeText "pam_duo.conf" configFile;
34 | mode = "0600";
35 | uid = config.ids.uids.root;
36 | target = "duo/pam_duo.conf";
37 | };
38 | in
39 | {
40 | options = {
41 | security.duosec = {
42 | ssh.enable = mkOption {
43 | type = types.bool;
44 | default = false;
45 | description = "If enabled, protect SSH logins with Duo Security.";
46 | };
47 |
48 | pam.enable = mkOption {
49 | type = types.bool;
50 | default = false;
51 | description = "If enabled, protect logins with Duo Security using PAM support.";
52 | };
53 |
54 | ikey = mkOption {
55 | type = types.str;
56 | description = "Integration key.";
57 | };
58 |
59 | skey = mkOption {
60 | type = types.str;
61 | description = "Secret key.";
62 | };
63 |
64 | host = mkOption {
65 | type = types.str;
66 | description = "Duo API hostname.";
67 | };
68 |
69 | group = mkOption {
70 | type = types.str;
71 | default = "";
72 | description = "Use Duo authentication for users only in this group.";
73 | };
74 |
75 | failmode = mkOption {
76 | type = types.enum [ "safe" "enum" ];
77 | default = "safe";
78 | description = ''
79 | On service or configuration errors that prevent Duo
80 | authentication, fail "safe" (allow access) or "secure" (deny
81 | access). The default is "safe".
82 | '';
83 | };
84 |
85 | pushinfo = mkOption {
86 | type = types.bool;
87 | default = false;
88 | description = ''
89 | Include information such as the command to be executed in
90 | the Duo Push message.
91 | '';
92 | };
93 |
94 | autopush = mkOption {
95 | type = types.bool;
96 | default = false;
97 | description = ''
98 | If true, Duo Unix will automatically send
99 | a push login request to the user’s phone, falling back on a
100 | phone call if push is unavailable. If
101 | false, the user will be prompted to
102 | choose an authentication method. When configured with
103 | autopush = yes, we recommend setting
104 | prompts = 1.
105 | '';
106 | };
107 |
108 | motd = mkOption {
109 | type = types.bool;
110 | default = false;
111 | description = ''
112 | Print the contents of /etc/motd to screen
113 | after a successful login.
114 | '';
115 | };
116 |
117 | prompts = mkOption {
118 | type = types.enum [ 1 2 3 ];
119 | default = 3;
120 | description = ''
121 | If a user fails to authenticate with a second factor, Duo
122 | Unix will prompt the user to authenticate again. This option
123 | sets the maximum number of prompts that Duo Unix will
124 | display before denying access. Must be 1, 2, or 3. Default
125 | is 3.
126 |
127 | For example, when prompts = 1, the user
128 | will have to successfully authenticate on the first prompt,
129 | whereas if prompts = 2, if the user
130 | enters incorrect information at the initial prompt, he/she
131 | will be prompted to authenticate again.
132 |
133 | When configured with autopush = true, we
134 | recommend setting prompts = 1.
135 | '';
136 | };
137 |
138 | acceptEnvFactor = mkOption {
139 | type = types.bool;
140 | default = false;
141 | description = ''
142 | Look for factor selection or passcode in the
143 | $DUO_PASSCODE environment variable before
144 | prompting the user for input.
145 |
146 | When $DUO_PASSCODE is non-empty, it will override
147 | autopush. The SSH client will need SendEnv DUO_PASSCODE in
148 | its configuration, and the SSH server will similarly need
149 | AcceptEnv DUO_PASSCODE.
150 | '';
151 | };
152 |
153 | fallbackLocalIP = mkOption {
154 | type = types.bool;
155 | default = false;
156 | description = ''
157 | Duo Unix reports the IP address of the authorizing user, for
158 | the purposes of authorization and whitelisting. If Duo Unix
159 | cannot detect the IP address of the client, setting
160 | fallbackLocalIP = yes will cause Duo Unix
161 | to send the IP address of the server it is running on.
162 |
163 | If you are using IP whitelisting, enabling this option could
164 | cause unauthorized logins if the local IP is listed in the
165 | whitelist.
166 | '';
167 | };
168 |
169 | permitTunnel = mkOption {
170 | type = types.bool;
171 | default = false;
172 | description = ''
173 | By default, when SSH forwarding, enabling Duo Security will
174 | disable tunneling. By enabling this, you potentially
175 | undermine some of the SSH based login security. Note this is
176 | not needed if you use PAM.
177 | '';
178 | };
179 |
180 | allowTcpForwarding = mkOption {
181 | type = types.bool;
182 | default = false;
183 | description = ''
184 | By default, when SSH forwarding, enabling Duo Security will
185 | disable TCP forwarding. By enabling this, you potentially
186 | undermine some of the SSH based login security. Note this is
187 | not needed if you use PAM.
188 | '';
189 | };
190 | };
191 | };
192 |
193 | config = mkIf (cfg.ssh.enable || cfg.pam.enable) {
194 | assertions =
195 | [ { assertion = !cfg.pam.enable;
196 | message = "PAM support is currently not implemented.";
197 | }
198 | ];
199 |
200 | environment.systemPackages = [ pkgs.duo-unix ];
201 |
202 | security.wrappers.login_duo.source = "${pkgs.duo-unix.out}/bin/login_duo";
203 | environment.etc = loginCfgFile ++ pamCfgFile;
204 |
205 | /* If PAM *and* SSH are enabled, then don't do anything special.
206 | If PAM isn't used, set the default SSH-only options. */
207 | services.openssh.extraConfig = mkIf (cfg.ssh.enable || cfg.pam.enable) (
208 | if cfg.pam.enable then "UseDNS no" else ''
209 | # Duo Security configuration
210 | ForceCommand ${config.security.wrapperDir}/login_duo
211 | ${optionalString (!cfg.permitTunnel) ''
212 | PermitTunnel no
213 | ''}
214 | ${optionalString (!cfg.allowTcpForwarding) ''
215 | AllowTcpForwarding no
216 | ''}
217 | '');
218 | };
219 | }
220 |
--------------------------------------------------------------------------------
/pkgs/emacs/config.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [
5 | emacs
6 | ];
7 | }
8 |
--------------------------------------------------------------------------------
/pkgs/gist/config.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [ gist ];
5 |
6 | environment.interactiveShellInit = ''
7 | alias gist='gist --private'
8 | '';
9 | }
10 |
--------------------------------------------------------------------------------
/pkgs/steam/chrootenv.nix:
--------------------------------------------------------------------------------
1 | { lib, buildFHSUserEnv, config }:
2 |
3 | buildFHSUserEnv {
4 | name = "steam";
5 |
6 | targetPkgs = pkgs:
7 | [ pkgs.steam-original
8 | pkgs.corefonts
9 | pkgs.curl
10 | pkgs.dbus
11 | pkgs.dpkg
12 | pkgs.mono
13 | pkgs.python
14 | pkgs.gnome2.zenity
15 | pkgs.xdg_utils
16 | ]
17 | ++ lib.optional (config.steam.java or false) pkgs.jdk
18 | ++ lib.optional (config.steam.primus or false) pkgs.primus
19 | ;
20 |
21 | multiPkgs = pkgs:
22 | [ pkgs.cairo
23 | pkgs.glib
24 | pkgs.gtk
25 | pkgs.gdk_pixbuf
26 | pkgs.pango
27 |
28 | pkgs.freetype
29 | pkgs.xlibs.libICE
30 | pkgs.xlibs.libSM
31 | pkgs.xlibs.libX11
32 | pkgs.xlibs.libXau
33 | pkgs.xlibs.libxcb
34 | pkgs.xlibs.libXcursor
35 | pkgs.xlibs.libXdamage
36 | pkgs.xlibs.libXdmcp
37 | pkgs.xlibs.libXext
38 | pkgs.xlibs.libXfixes
39 | pkgs.xlibs.libXi
40 | pkgs.xlibs.libXinerama
41 | pkgs.xlibs.libXrandr
42 | pkgs.xlibs.libXrender
43 | pkgs.xlibs.libXScrnSaver
44 | pkgs.xlibs.libXtst
45 | pkgs.xlibs.libXxf86vm
46 |
47 | pkgs.ffmpeg
48 | pkgs.libpng12
49 | pkgs.mesa
50 | pkgs.SDL
51 | pkgs.SDL2
52 |
53 | pkgs.libgcrypt
54 | pkgs.zlib
55 |
56 | pkgs.alsaLib
57 | pkgs.libvorbis
58 | pkgs.openal
59 | pkgs.libpulseaudio
60 |
61 | # pkgs.flashplayer
62 |
63 | pkgs.gst_all_1.gst-plugins-ugly # "Audiosurf 2" needs this
64 | ];
65 |
66 | extraBuildCommandsMulti = ''
67 | cd usr/lib
68 | ln -sf ../lib64/steam steam
69 | '';
70 |
71 | profile = ''
72 | # Ugly workaround for https://github.com/ValveSoftware/steam-for-linux/issues/3504
73 | export LD_PRELOAD=/lib32/libpulse.so:/lib64/libpulse.so:/lib32/libasound.so:/lib64/libasound.so
74 | '';
75 |
76 | runScript = "steam";
77 | }
78 |
--------------------------------------------------------------------------------
/pkgs/tinc/default.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 | with lib;
3 |
4 | let
5 |
6 | cfg = config.services.tinc;
7 |
8 | in
9 |
10 | {
11 |
12 | ###### interface
13 |
14 | options = {
15 |
16 | services.tinc = {
17 |
18 | networks = mkOption {
19 | default = { };
20 | type = with types; attrsOf (submodule {
21 | options = {
22 |
23 | extraConfig = mkOption {
24 | default = "";
25 | type = types.lines;
26 | description = ''
27 | Extra lines to add to the tinc service configuration file.
28 | '';
29 | };
30 |
31 | name = mkOption {
32 | default = null;
33 | type = types.nullOr types.str;
34 | description = ''
35 | The name of the node which is used as an identifier when communicating
36 | with the remote nodes in the mesh. If null then the hostname of the system
37 | is used to derive a name (note that tinc may replace non-alphanumeric characters in
38 | hostnames by underscores).
39 | '';
40 | };
41 |
42 | ed25519PrivateKeyFile = mkOption {
43 | default = null;
44 | type = types.nullOr types.path;
45 | description = ''
46 | Path of the private ed25519 keyfile.
47 | '';
48 | };
49 |
50 | debugLevel = mkOption {
51 | default = 0;
52 | type = types.addCheck types.int (l: l >= 0 && l <= 5);
53 | description = ''
54 | The amount of debugging information to add to the log. 0 means little
55 | logging while 5 is the most logging. man tincd for
56 | more details.
57 | '';
58 | };
59 |
60 | hosts = mkOption {
61 | default = { };
62 | type = types.attrsOf types.lines;
63 | description = ''
64 | The name of the host in the network as well as the configuration for that host.
65 | This name should only contain alphanumerics and underscores.
66 | '';
67 | };
68 |
69 | interfaceType = mkOption {
70 | default = "tun";
71 | type = types.enum [ "tun" "tap" ];
72 | description = ''
73 | The type of virtual interface used for the network connection
74 | '';
75 | };
76 |
77 | listenAddress = mkOption {
78 | default = null;
79 | type = types.nullOr types.str;
80 | description = ''
81 | The ip address to listen on for incoming connections.
82 | '';
83 | };
84 |
85 | bindToAddress = mkOption {
86 | default = null;
87 | type = types.nullOr types.str;
88 | description = ''
89 | The ip address to bind to (both listen on and send packets from).
90 | '';
91 | };
92 |
93 | package = mkOption {
94 | type = types.package;
95 | default = pkgs.tinc_pre;
96 | defaultText = "pkgs.tinc_pre";
97 | description = ''
98 | The package to use for the tinc daemon's binary.
99 | '';
100 | };
101 |
102 | chroot = mkOption {
103 | default = true;
104 | type = types.bool;
105 | description = ''
106 | Change process root directory to the directory where the config file is located (/etc/tinc/netname/), for added security.
107 | The chroot is performed after all the initialization is done, after writing pid files and opening network sockets.
108 |
109 | Note that tinc can't run scripts anymore (such as tinc-down or host-up), unless it is setup to be runnable inside chroot environment.
110 | '';
111 | };
112 | };
113 | });
114 |
115 | description = ''
116 | Defines the tinc networks which will be started.
117 | Each network invokes a different daemon.
118 | '';
119 | };
120 | };
121 |
122 | };
123 |
124 |
125 | ###### implementation
126 |
127 | config = mkIf (cfg.networks != { }) {
128 |
129 | environment.etc = fold (a: b: a // b) { }
130 | (flip mapAttrsToList cfg.networks (network: data:
131 | flip mapAttrs' data.hosts (host: text: nameValuePair
132 | ("tinc/${network}/hosts/${host}")
133 | ({ mode = "0644"; user = "tinc.${network}"; inherit text; })
134 | ) // {
135 | "tinc/${network}/tinc.conf" = {
136 | mode = "0444";
137 | text = ''
138 | Name = ${if data.name == null then "$HOST" else data.name}
139 | DeviceType = ${data.interfaceType}
140 | ${optionalString (data.ed25519PrivateKeyFile != null) "Ed25519PrivateKeyFile = ${data.ed25519PrivateKeyFile}"}
141 | ${optionalString (data.listenAddress != null) "ListenAddress = ${data.listenAddress}"}
142 | ${optionalString (data.bindToAddress != null) "BindToAddress = ${data.bindToAddress}"}
143 | Interface = tinc.${network}
144 | ${data.extraConfig}
145 | '';
146 | };
147 | }
148 | ));
149 |
150 | networking.interfaces = flip mapAttrs' cfg.networks (network: data: nameValuePair
151 | ("tinc.${network}")
152 | ({
153 | virtual = true;
154 | virtualType = "${data.interfaceType}";
155 | })
156 | );
157 |
158 | systemd.services = flip mapAttrs' cfg.networks (network: data: nameValuePair
159 | ("tinc.${network}")
160 | ({
161 | description = "Tinc Daemon - ${network}";
162 | wantedBy = [ "multi-user.target" ];
163 | after = [ "network.target" ];
164 | path = [ data.package ];
165 | restartTriggers =
166 | let
167 | drvlist = [ config.environment.etc."tinc/${network}/tinc.conf".source ]
168 | ++ mapAttrsToList (host: _: config.environment.etc."tinc/${network}/hosts/${host}".source) data.hosts;
169 | in # drvlist might be too long to be used directly
170 | [ (builtins.hashString "sha256" (concatMapStrings (d: d.outPath) drvlist)) ];
171 | serviceConfig = {
172 | Type = "simple";
173 | Restart = "always";
174 | RestartSec = "3";
175 | ExecStart = "${data.package}/bin/tincd -D -U tinc.${network} -n ${network} ${optionalString (data.chroot) "-R"} --pidfile /run/tinc.${network}.pid -d ${toString data.debugLevel}";
176 | };
177 | preStart = ''
178 | mkdir -p /etc/tinc/${network}/hosts
179 | chown tinc.${network} /etc/tinc/${network}/hosts
180 |
181 | /run/current-system/sw/bin/ifconfig tinc.${network} yeah netmask nah up
182 | /run/current-system/sw/bin/ifconfig tinc.${network}:0 yeah netmask nah up
183 |
184 | # Determine how we should generate our keys
185 | if type tinc >/dev/null 2>&1; then
186 | # Tinc 1.1+ uses the tinc helper application for key generation
187 | ${if data.ed25519PrivateKeyFile != null then " # Keyfile managed by nix" else ''
188 | # Prefer ED25519 keys (only in 1.1+)
189 | [ -f "/etc/tinc/${network}/ed25519_key.priv" ] || tinc -n ${network} generate-ed25519-keys
190 | ''}
191 | # Otherwise use RSA keys
192 | [ -f "/etc/tinc/${network}/rsa_key.priv" ] || tinc -n ${network} generate-rsa-keys 4096
193 | else
194 | # Tinc 1.0 uses the tincd application
195 | [ -f "/etc/tinc/${network}/rsa_key.priv" ] || tincd -n ${network} -K 4096
196 | fi
197 | '';
198 | })
199 | );
200 |
201 | environment.systemPackages = let
202 | cli-wrappers = pkgs.stdenv.mkDerivation {
203 | name = "tinc-cli-wrappers";
204 | buildInputs = [ pkgs.makeWrapper ];
205 | buildCommand = ''
206 | mkdir -p $out/bin
207 | ${concatStringsSep "\n" (mapAttrsToList (network: data:
208 | optionalString (versionAtLeast data.package.version "1.1pre") ''
209 | makeWrapper ${data.package}/bin/tinc "$out/bin/tinc.${network}" \
210 | --add-flags "--pidfile=/run/tinc.${network}.pid"
211 | '') cfg.networks)}
212 | '';
213 | };
214 | in [ cli-wrappers ];
215 |
216 | users.extraUsers = flip mapAttrs' cfg.networks (network: _:
217 | nameValuePair ("tinc.${network}") ({
218 | description = "Tinc daemon user for ${network}";
219 | isSystemUser = true;
220 | })
221 | );
222 |
223 | };
224 |
225 | }
226 |
--------------------------------------------------------------------------------
/pkgs/vim/config.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 |
5 | nixpkgs.config.vim = {
6 | ftNixSupport = true;
7 | };
8 |
9 | environment.interactiveShellInit = ''
10 | alias vi='vim'
11 | '';
12 |
13 | environment.variables = {
14 | EDITOR = [ "${pkgs.vim}/bin/vim" ];
15 | };
16 |
17 | environment.etc.vimrc = {
18 | text = ''
19 | " Use Vim settings, rather than Vi settings (much better!).
20 | " This must be first, because it changes other options as a side effect.
21 | set nocompatible
22 |
23 | " allow backspacing over everything in insert mode
24 | set backspace=indent,eol,start
25 |
26 | " keep 1024 lines of command line history
27 | set history=1024
28 |
29 | " use syntax highlighting if possible
30 | if has("syntax")
31 | syntax on
32 | endif
33 |
34 | " spaces not tabs
35 | set tabstop=2
36 | set shiftwidth=2
37 | set expandtab
38 |
39 | " show the cursor position all the time
40 | set ruler
41 | '';
42 | };
43 |
44 | environment.systemPackages = [ pkgs.vim_configurable ];
45 | }
46 |
--------------------------------------------------------------------------------
/pkgs/zsh/config.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | programs.zsh.enable = true;
5 | programs.zsh.ohMyZsh.enable = true;
6 |
7 | #environment.variables = {
8 | # OH_MY_ZSH = [ "${pkgs.oh-my-zsh}/share/oh-my-zsh" ];
9 | #};
10 | }
11 |
--------------------------------------------------------------------------------
/profiles/android.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | {
4 | # install packages for Android development
5 | environment.systemPackages = with pkgs; [
6 | androidndk
7 | androidsdk
8 | ];
9 |
10 | # FIXME: Can't seem to get adb to work without root
11 | #services.udev.extraRules =
12 | # ''
13 | # SUBSYSTEM=="usb", ATTR(idVendor)=="18D1", MODE="0666" OWNER="ghuntley"
14 | # SUBSYSTEM=="usb", ATTR(idVendor)=="22B8", MODE="0666" OWNER="ghuntley"
15 | # '';
16 | }
17 |
--------------------------------------------------------------------------------
/profiles/audio.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | # Enable PulseAudio
5 | hardware.pulseaudio = {
6 | enable = true;
7 | package = pkgs.pulseaudioFull;
8 | };
9 |
10 | environment.systemPackages = with pkgs; [
11 | apulse # Allows ALSA applications to use pulse
12 | pavucontrol # PulseAudio volume control
13 |
14 | # Audio tools
15 | audacity
16 | ardour
17 | milkytracker
18 | ];
19 |
20 | # # Enable HDMI audio for pulse
21 | # hardware.pulseaudio.configFile = pkgs.stdenv.mkDerivation rec {
22 | # name = "pulseaudio-config";
23 | # buildCommand = ''
24 | # cat ${pkgs.pulseaudioFull}/etc/pulse/default.pa > $out
25 | # echo 'load-module module-alsa-sink device=hw:1,7' >> $out
26 | # '';
27 | # };
28 | }
29 |
--------------------------------------------------------------------------------
/profiles/bluetooth.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | hardware.bluetooth.enable = true;
5 |
6 | environment.systemPackages = with pkgs; [
7 | bluez-tools
8 | ];
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/profiles/cuda.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [
5 | cudatoolkit
6 | ];
7 |
8 | services.xserver.videoDrivers = [ "nvidia" ];
9 |
10 | systemd.services.nvidia-control-devices = {
11 | wantedBy = [ "multi-user.target" ];
12 | serviceConfig.ExecStart = "${pkgs.linuxPackages.nvidia_x11}/bin/nvidia-smi";
13 | };
14 |
15 | nixpkgs.config.allowUnfree = true;
16 |
17 | system.activationScripts =
18 | {
19 | # Enable OpenCL
20 | opencl =
21 | ''
22 | cd /etc
23 | mkdir -p ./OpenCL/vendors
24 | cd ./OpenCL/vendors
25 | # echo '${pkgs.linuxPackages.nvidia_x11}' > nvidia.icd
26 | '';
27 | };
28 | }
29 |
--------------------------------------------------------------------------------
/profiles/default.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 |
5 | imports = [
6 | ../pkgs/bash/config.nix
7 | ../pkgs/emacs/config.nix
8 | ../pkgs/gist/config.nix
9 | ../pkgs/vim/config.nix
10 | ../pkgs/zsh/config.nix
11 | ];
12 |
13 | # List packages installed in system profile. To search by name, run:
14 | # nix-env -qaP | grep wget
15 | environment.systemPackages = with pkgs; [
16 | ack
17 | apg # random password generation
18 | aspell
19 | aspellDicts.en
20 | bind # nslookup, dig
21 | blackbox # safely store secrets in git
22 | bridge-utils
23 | ctags
24 | curl
25 | dos2unix
26 | duplicity
27 | elinks
28 | expect
29 | file
30 | git-lfs
31 | gitAndTools.gitFull
32 | gnumake
33 | gnupg
34 | htop
35 | idutils
36 | iftop
37 | iotop
38 | lsof
39 | mkpasswd
40 | mosh
41 | most
42 | ncftp
43 | ncurses
44 | nix-prefetch-scripts
45 | nix-repl
46 | nmap
47 | nox # https://github.com/madjar/nox
48 | openssl
49 | p7zip
50 | pciutils
51 | pmutils
52 | psmisc
53 | stdenv
54 | strace
55 | sudo
56 | sysstat
57 | tcpdump
58 | tmux
59 | tmuxinator
60 | unison
61 | unzip
62 | usbutils
63 | vim_configurable
64 | w3m
65 | wget
66 | youtube-dl
67 | zip
68 | zsh
69 | ];
70 |
71 | # custom packages
72 | #nixpkgs.config.packageOverrides = pkgs: rec {
73 | # heirloom-mailx = pkgs.callPackage ../pkgs/heirloom-mailx/default.nix { };
74 | # unison_2_40_102 = pkgs.callPackage ../pkgs/unison/unison-2.40.102.nix { lablgtk = pkgs.ocamlPackages.lablgtk; };
75 | #};
76 |
77 | # Enable zsh as a login shell
78 | programs.zsh.enable = true;
79 | }
80 |
--------------------------------------------------------------------------------
/profiles/desktop.nix:
--------------------------------------------------------------------------------
1 | { pkgs, ... }:
2 |
3 | {
4 |
5 | services.xserver = {
6 | enable = true;
7 | enableCtrlAltBackspace = true;
8 |
9 | windowManager = {
10 | i3.enable = true;
11 | i3.package = pkgs.i3-gaps;
12 | default = "i3";
13 | };
14 |
15 | displayManager = {
16 | sessionCommands = "i3status &";
17 | };
18 |
19 | desktopManager = {
20 | default = "none";
21 | xterm.enable = false;
22 | };
23 |
24 | };
25 |
26 | nixpkgs.config = {
27 | chromium = {
28 | jre = false;
29 | enableGoogleTalkPlugin = true;
30 | enableAdobeFlash = false;
31 | enablePepperPDF = true;
32 | };
33 |
34 | firefox = {
35 | jre = false;
36 | enableGoogleTalkPlugin = true;
37 | enableAdobeFlash = false;
38 | enablePepperPDF = true;
39 | };
40 | };
41 |
42 | fonts = {
43 | enableFontDir = true;
44 | enableGhostscriptFonts = true;
45 | fonts = with pkgs; [
46 | corefonts
47 | dejavu_fonts
48 | emojione
49 | fira-code
50 | font-awesome-ttf
51 | inconsolata
52 | proggyfonts
53 | powerline-fonts
54 | source-code-pro
55 | source-sans-pro
56 | source-serif-pro
57 | terminus_font
58 | ubuntu_font_family
59 | vistafonts
60 | ];
61 | };
62 |
63 | environment.systemPackages = with pkgs; [
64 | xorg.xrdb
65 | xorg.setxkbmap
66 | xorg.iceauth # required for KDE applications (it's called by dcopserver)
67 | xorg.xlsclients
68 | xorg.xset
69 | xorg.xsetroot
70 | xorg.xinput
71 | xorg.xprop
72 | xorg.xauth
73 | xorg.xmodmap
74 | xorg.xbacklight
75 | numlockx
76 | xautolock
77 | xss-lock
78 | xtitle
79 | xclip
80 |
81 | imagemagick
82 |
83 | xterm
84 | xdg_utils
85 |
86 | gparted
87 |
88 | rofi
89 | dmenu
90 | feh # for background image
91 | i3lock # screen lock
92 | i3status # sys info
93 | scrot # for screenshot
94 | hyper
95 | terminator
96 | alacritty
97 |
98 | epdfview
99 | chromium
100 | dunst
101 | uget
102 | wireshark
103 | firefox
104 | gimp
105 | inkscape
106 | xfontsel
107 | slack
108 | atom
109 | zoom-us
110 | vimHugeX
111 | i3minator
112 | evince
113 | libreoffice
114 | vlc
115 |
116 | keybase
117 | keybase-gui
118 |
119 | gnome3.nautilus
120 | gnome3.eog
121 |
122 | google-play-music-desktop-player
123 | messenger-for-desktop
124 |
125 | vscode
126 | ];
127 |
128 |
129 | # Enable corsair keyboard/mouse
130 | hardware.ckb.enable = true;
131 |
132 | # Enable 3D acceleration for 32bit applications (e.g. wine)
133 | hardware.opengl.driSupport32Bit = true;
134 | hardware.opengl.driSupport = true;
135 | hardware.opengl.enable = true;
136 |
137 | # Allow ChromeCast to send/receive packets
138 | # http://askubuntu.com/a/326224/177448
139 | networking.firewall.extraCommands = ''
140 | iptables -I INPUT -p udp -m udp --dport 32768:60999 -j ACCEPT
141 | '';
142 | }
143 |
--------------------------------------------------------------------------------
/profiles/development.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | {
4 | imports = [
5 | ./haskell.nix
6 | ];
7 |
8 | # install development packages
9 | environment.systemPackages = with pkgs; [
10 | zlib
11 | ];
12 |
13 | # custom packages
14 | nixpkgs.config.packageOverrides = pkgs: rec {
15 | };
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/profiles/docker.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | {
4 | virtualisation.libvirtd.enable = true;
5 | virtualisation.lxc.enable = true;
6 | virtualisation.lxc.usernetConfig = ''
7 | bfo veth lxcbr0 10
8 | '';
9 | virtualisation.docker.enable = true;
10 | virtualisation.docker.storageDriver = "overlay";
11 | }
--------------------------------------------------------------------------------
/profiles/dotnet.nix:
--------------------------------------------------------------------------------
1 | { pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [
5 |
6 | mono50
7 | monodevelop
8 |
9 | ];
10 | }
11 |
--------------------------------------------------------------------------------
/profiles/drawing.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [
5 | krita
6 | ];
7 |
8 | services.xserver.wacom.enable = true;
9 | }
10 |
--------------------------------------------------------------------------------
/profiles/email.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [
5 | offlineimap
6 | notmuch
7 | python27Packages.alot
8 | python36Packages.afew
9 | ];
10 | }
11 |
--------------------------------------------------------------------------------
/profiles/games.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [
5 | openra
6 | prboom
7 | scorched3d
8 |
9 | # Game related tools
10 | steam
11 | ];
12 |
13 | nixpkgs.config.packageOverrides = pkgs: rec {
14 | # steam = pkgs.callPackage ../pkgs/steam/chrootenv.nix { };
15 | };
16 | }
17 |
--------------------------------------------------------------------------------
/profiles/graphics.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | {
4 | # install graphics-related packages
5 | environment.systemPackages = with pkgs; [
6 | blender
7 | gimp
8 | inkscape
9 | ];
10 | }
11 |
--------------------------------------------------------------------------------
/profiles/haskell.nix:
--------------------------------------------------------------------------------
1 | { pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [
5 |
6 | ctags
7 |
8 | cabal2nix
9 | cabal-install
10 | stack
11 |
12 | haskell.compiler.ghc822
13 |
14 | # libraries
15 | haskellPackages.alex
16 | haskellPackages.happy
17 | haskellPackages.hakyll
18 |
19 | # tools
20 | #haskellPackages.hscope
21 | #haskellPackages.argon # code complexity (req: haskell 7.10)
22 | haskellPackages.codex # ctags file generator for cabal project dependencies
23 | haskellPackages.ghc-mod # ghc-mod is a backend program to enrich editors
24 | haskellPackages.ghcid # GHCi as a daemon
25 | haskellPackages.hasktags # Produces ctags "tags" and etags "TAGS" files for Haskell programs
26 | haskellPackages.hlint # linter
27 | haskellPackages.hoogle # type signature search
28 | haskellPackages.hpack # yaml based package format
29 | haskellPackages.hspec # testing framework
30 | haskellPackages.pointfree # http://pointfree.io/
31 | haskellPackages.pointful # https://github.com/23Skidoo/pointful
32 | haskellPackages.stylish-haskell # pretty printer
33 | haskellPackages.tasty # testing framework
34 | haskellPackages.weeder # dead code detection
35 |
36 | ];
37 | }
38 |
--------------------------------------------------------------------------------
/profiles/homeautomation.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [
5 | hue-cli
6 | ];
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/profiles/kernel.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | {
4 | # Debug options for kernel hacking
5 | nixpkgs.config.packageOverrides = pkgs: rec {
6 | stdenv = pkgs.stdenv //
7 | {
8 | platform = pkgs.stdenv.platform //
9 | {
10 | kernelExtraConfig = ''
11 | DEBUG_KERNEL y
12 | MAGIC_SYSRQ y
13 | KALLSYMS y
14 | IKCONFIG y
15 | IKCONFIG_PROC y
16 | DEBUG_INFO y
17 | FRAME_POINTER y
18 | DEBUG_STACKOVERFLOW y
19 | DEBUG_STACK_USAGE y
20 | '';
21 | };
22 | };
23 | };
24 | }
25 |
--------------------------------------------------------------------------------
/profiles/latex.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [
5 | pandoc
6 | ];
7 | }
8 |
--------------------------------------------------------------------------------
/profiles/livecoding.nix:
--------------------------------------------------------------------------------
1 | { pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [
5 |
6 | obs-studio
7 |
8 | ];
9 | }
10 |
--------------------------------------------------------------------------------
/profiles/maclaptop.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [
5 | efivar # used to mute macbook air startup beep
6 | lightum # macbook light sensor daemon
7 | ];
8 |
9 | services = {
10 | xserver = {
11 | synaptics = {
12 | enable = true;
13 | dev = "/dev/input/event*";
14 | twoFingerScroll = true;
15 | tapButtons = false;
16 | accelFactor = "0.06";
17 | buttonsMap = [ 1 3 2 ];
18 | palmDetect = true;
19 | additionalOptions = ''
20 | Option "VertScrollDelta" "-180" # scroll sensitivity, the bigger the negative number = less sensitive
21 | Option "HorizScrollDelta" "-180"
22 | Option "FingerLow" "40"
23 | Option "FingerHigh" "70"
24 | Option "Resolution" "270" # Pointer sensitivity, this is for a retina screen, so you'll probably need to change this for an air
25 | '';
26 | };
27 | };
28 | };
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/profiles/mathematics.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [
5 | gnuplot
6 | ];
7 | }
8 |
--------------------------------------------------------------------------------
/profiles/netjail.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 |
5 | # thx pjf - https://twitter.com/pjf/status/956338472863727616
6 | # usage: `sg netjail cmdname`
7 |
8 | networking.firewall.enable = true;
9 | networking.firewall.extraCommands = ''
10 | # Always allow loopback traffic
11 | iptables -A OUTPUT -o lo -j ACCEPT
12 |
13 | # Block any traffic from the netjail group
14 | iptables -A OUTPUT -m owner --gid-owner netjail -j LOG --log-prefix 'Netjailed process blocked: '
15 | #iptables -A OUTPUT -m owner --gid-owner netjail -j REJECT
16 | '';
17 |
18 |
19 | users.extraGroups = {
20 | netjail = { };
21 | };
22 |
23 | }
24 |
25 |
26 |
--------------------------------------------------------------------------------
/profiles/networking.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | {
4 | # install networking packages
5 | environment.systemPackages = with pkgs; [
6 | etherape
7 | ettercap
8 | tcpdump
9 | wireshark
10 | ];
11 | }
12 |
--------------------------------------------------------------------------------
/profiles/powermanagement.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 |
5 | services.acpid =
6 | {
7 | enable = true;
8 |
9 | # Suspend on power button press
10 | powerEventCommands = ''
11 | pid_file=/var/run/button-suspend.pid
12 |
13 | if [ -e "$pid_file" ]; then
14 | wait_pid=$(cat "$pid_file")
15 | kill -s 0 "$wait_pid"
16 | if [ $? -eq 0 ]; then
17 | # An instance of the "button_wait" process is already running.
18 | # Don't do anything, effectively "de-bouncing" the power button.
19 | exit 0
20 | else
21 | # An instance of the "button_wait" process ran, but it did not clean up.
22 | rm "$pid_file"
23 | fi
24 | fi
25 | # Make new "button_wait" process to de-bounce the button WITHOUT blocking.
26 | # If we were to sleep and block the thread of this script, then acpid
27 | # would just wait until we were done sleeping to process the queue of
28 | # bounced power button events.
29 | (sleep 10; rm "$pid_file") &
30 | echo "$!" > "$pid_file"
31 |
32 | systemctl hibernate
33 | #${pkgs.pmutils}/bin/pm-suspend
34 | '';
35 | };
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/profiles/printing.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | {
4 | services.printing = {
5 | enable = true;
6 | drivers = with pkgs; [ gutenprint gutenprintBin hplipWithPlugin ];
7 | };
8 | }
9 |
--------------------------------------------------------------------------------
/profiles/redshift.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | services.redshift = {
5 | enable = true;
6 | latitude = "33.7710";
7 | longitude = "-150.9063";
8 | temperature.night = 4000;
9 | brightness.night = "0.8";
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/profiles/ruby.nix:
--------------------------------------------------------------------------------
1 | { pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [
5 |
6 | jekyll
7 | ruby
8 | bundler
9 | bundix
10 |
11 | ];
12 | }
13 |
--------------------------------------------------------------------------------
/profiles/rust.nix:
--------------------------------------------------------------------------------
1 | { pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [
5 |
6 | cargo
7 | rustc
8 | rustfmt
9 |
10 | ];
11 | }
12 |
--------------------------------------------------------------------------------
/profiles/steam.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | {
4 | # Allow the Steam controller to be configured by Steam
5 | services.udev.extraRules =
6 | ''
7 | # This rule is needed for basic functionality of the controller in Steam and keyboard/mouse emulation
8 | SUBSYSTEM=="usb", ATTRS{idVendor}=="28de", MODE="0666"
9 |
10 | # This rule is necessary for gamepad emulation
11 | KERNEL=="uinput", MODE="0660", GROUP="ghuntley", OPTIONS+="static_node=uinput"
12 | '';
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/profiles/virtualization.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | nixpkgs.config = {
5 | };
6 |
7 | environment.systemPackages = with pkgs; [
8 | kvm
9 | qemu
10 | vagrant
11 | virtmanager
12 | ];
13 |
14 | virtualisation.libvirtd = {
15 | enable = true;
16 | onShutdown = "shutdown";
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/roles/btsync.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | let secrets = import ../secrets.nix;
4 | in
5 | {
6 | imports = [
7 | ];
8 |
9 | services.btsync = {
10 | enableWebUI = false;
11 | httpListenAddr = "yeah";
12 | httpListenPort = nah;
13 | httpLogin = secrets.btsync.username;
14 | httpPass = secrets.btsync.password;
15 | apiKey = secrets.btsync.apiKey;
16 |
17 | downloadLimit = 0;
18 | uploadLimit = 0;
19 |
20 | directoryRoot = "/yeah/nah";
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/roles/gitlab-runner.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | let secrets = import ../secrets.nix;
4 | in
5 | {
6 | imports = [
7 | # Enable docker.
8 | ../profiles/docker.nix
9 | ];
10 |
11 | services.gitlab-runner = {
12 | enable = true;
13 | configOptions = {
14 | concurrent = 2;
15 | ruenners = [{
16 | name = "docker-nix-1.11";
17 | url = secrets.gitlab-runner.url;
18 | token = secrets.gitlab-runner.token;
19 | executor = "docker";
20 | builds_dir = "/yeahnah/gitlab-runner/builds";
21 | docker = {
22 | image = "nixos/nix:1.11";
23 | privileged = false;
24 | disable_cache = false;
25 | cache_dir = "/yeahnah/gitlab-runner/cache";
26 | };
27 | }];
28 | };
29 | };
30 | }
31 |
--------------------------------------------------------------------------------
/roles/taskwarrior.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | environment.systemPackages = with pkgs; [
5 | taskwarrior
6 | ];
7 |
8 | services.taskserver.enable = true;
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/secrets.nix:
--------------------------------------------------------------------------------
1 | {
2 | # hosts
3 | extraHosts = ''
4 | 127.0.0.1 yeah nah
5 | '';
6 |
7 | # btsync
8 | btsync.username = "admin";
9 | btsync.password = "yeah";
10 | btsync.apiKey = "nah";
11 |
12 | # gitlab
13 | gitlab-runner = {
14 | url = "yeah";
15 | token = "nah";
16 | };
17 |
18 | # sshd
19 | sshKeys = {
20 | yeah = [
21 | "nah"
22 | ];
23 | };
24 |
25 | tincHosts = {
26 | yeah = ''
27 | nah
28 | '';
29 | };
30 | }
31 |
--------------------------------------------------------------------------------
/services/default.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | imports = [
5 | ./duosec.nix
6 | ./fail2ban.nix
7 | ./fstrim.nix
8 | ./mosh.nix
9 | ./ntp.nix
10 | ./sshd.nix
11 | ./tinc.nix
12 | ];
13 | }
14 |
--------------------------------------------------------------------------------
/services/duosec.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 | with lib;
3 |
4 | {
5 | disabledModules = [ "security/duosec.nix" ];
6 | imports = [ ../pkgs/duosec/default.nix ];
7 |
8 | security.duosec = {
9 | ssh.enable = true;
10 | # pam.enable = true; <-- not currently impl
11 |
12 | allowTcpForwarding = true;
13 | permitTunnel = true;
14 |
15 | ikey = "yeahnah";
16 | skey = "yeahnah";
17 | host = "yeahnah";
18 |
19 | # when using autopush, prompts should be set to 1
20 | autopush = true;
21 | prompts = 1;
22 |
23 | motd = true;
24 | };
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/services/fail2ban.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | services.fail2ban = {
5 | enable = true;
6 |
7 | jails.DEFAULT =
8 | ''
9 | bantime = 3600
10 | '';
11 |
12 | jails.sshd =
13 | ''
14 | filter = sshd
15 | maxretry = 4
16 | action = iptables[name=ssh, port=ssh, protocol=tcp]
17 | enabled = true
18 | '';
19 |
20 | jails.sshd-ddos =
21 | ''
22 | filter = sshd-ddos
23 | maxretry = 2
24 | action = iptables[name=ssh, port=ssh, protocol=tcp]
25 | enabled = true
26 | '';
27 |
28 | jails.postfix =
29 | ''
30 | filter = postfix
31 | maxretry = 3
32 | action = iptables[name=postfix, port=smtp, protocol=tcp]
33 | enabled = true
34 | '';
35 |
36 | jails.postfix-sasl =
37 | ''
38 | filter = postfix-sasl
39 | maxretry = 3
40 | action = iptables[name=postfix, port=smtp, protocol=tcp]
41 | enabled = true
42 | '';
43 |
44 | jails.postfix-ddos =
45 | ''
46 | filter = postfix-ddos
47 | maxretry = 3
48 | action = iptables[name=postfix, port=submission, protocol=tcp]
49 | bantime = 7200
50 | enabled = true
51 | '';
52 | };
53 |
54 | environment.etc."fail2ban/filter.d/postfix-ddos.conf".text =
55 | ''
56 | [Definition]
57 | failregex = lost connection after EHLO from \S+\[\]
58 | '';
59 |
60 | # Limit stack size to reduce memory usage
61 | systemd.services.fail2ban.serviceConfig.LimitSTACK = 256 * 1024;
62 | }
63 |
--------------------------------------------------------------------------------
/services/fstrim.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | systemd.services.fstrim = {
5 | description = "Trim SSD Disks";
6 | serviceConfig.Type = "oneshot";
7 | serviceConfig.ExecStart = "${pkgs.utillinux}/bin/fstrim -a -v";
8 | startAt = "02:35";
9 | };
10 | }
11 |
--------------------------------------------------------------------------------
/services/mosh.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 | with lib;
3 |
4 | {
5 | # resolves nix-shell failing with Error in tempdir() using /run/user/1000/nix-shell.XXXXX
6 | # https://nixos.wiki/wiki/Mosh
7 | system.activationScripts.systemd = stringAfter["groups"]
8 | ''
9 | loginctl enable-linger yeahnah
10 | '';
11 |
12 | environment.systemPackages = [ pkgs.mosh ];
13 |
14 | networking.firewall = {
15 | allowedUDPPortRanges = [
16 | { from = 60000; to = 61000; } # mosh
17 | ];
18 | };
19 |
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/services/ntp.nix:
--------------------------------------------------------------------------------
1 | { config, ... }:
2 |
3 | {
4 | services.ntp.enable = false;
5 |
6 | services.chrony = {
7 | enable = true;
8 | servers = [
9 | "0.pool.ntp.org"
10 | "1.pool.ntp.org"
11 | "2.pool.ntp.org"
12 | "3.pool.ntp.org"
13 | ];
14 | };
15 | }
16 |
--------------------------------------------------------------------------------
/services/ssh-phone-home.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | with lib;
4 |
5 | let
6 | inherit (pkgs) openssh;
7 | cfg = config.services.ssh-phone-home;
8 | in
9 |
10 | {
11 |
12 | ###### interface
13 |
14 | options = {
15 | services.ssh-phone-home = {
16 | enable = mkOption {
17 | type = types.bool;
18 | default = false;
19 | description = ''
20 | Whether to enable a "phone home" reverse SSH proxy.
21 | '';
22 | };
23 |
24 | persist = mkOption {
25 | type = types.bool;
26 | default = true;
27 | description = ''
28 | When this is set to true, the service will persistently attempt to
29 | reconnect at intervals whenever the port forwarding operation fails.
30 | This is the recommended behavior for reliable operation. If one finds
31 | oneself in an environment where this kind of behavior might draw the
32 | suspicion of a network administrator, it might be a good idea to
33 | set this option to false (or not use ssh-phone-home
34 | at all).
35 | '';
36 | };
37 |
38 | localUser = mkOption {
39 | description = ''
40 | Local user to connect as (i.e. the user with password-less SSH keys).
41 | '';
42 | };
43 |
44 | remoteHostname = mkOption {
45 | description = ''
46 | The remote host to connect to. This should be the host outside of the
47 | firewall or NAT.
48 | '';
49 | };
50 |
51 | remotePort = mkOption {
52 | default = 22;
53 | description = ''
54 | The port on which to connect to the remote host via SSH protocol.
55 | '';
56 | };
57 |
58 | remoteUser = mkOption {
59 | description = ''
60 | The username to connect to the remote host as.
61 | '';
62 | };
63 |
64 | bindPort = mkOption {
65 | default = 2222;
66 | description = ''
67 | The port to bind and listen to on the remote host.
68 | '';
69 | };
70 | };
71 | };
72 |
73 |
74 | ###### implementation
75 |
76 | config = mkIf cfg.enable {
77 | systemd.services.ssh-phone-home =
78 | {
79 | description = ''
80 | Reverse SSH tunnel as a service
81 | '';
82 |
83 | # FIXME: This isn't triggered until a reboot, and probably won't work between suspends.
84 | wantedBy = [ "multi-user.target" ];
85 |
86 | serviceConfig = with cfg; {
87 | User = cfg.localUser;
88 | } // (if cfg.persist then
89 | {
90 | # Restart every 10 seconds on failure
91 | RestartSec = 10;
92 | Restart = "on-failure";
93 | }
94 | else {}
95 | );
96 |
97 | script = with cfg; ''
98 | ${openssh}/bin/ssh -NTC -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes -R ${toString bindPort}:localhost:22 -l ${remoteUser} -p ${toString remotePort} ${remoteHostname}
99 | '';
100 | };
101 | };
102 | }
103 |
--------------------------------------------------------------------------------
/services/sshd.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | # Enable the OpenSSH daemon.
5 | services.openssh = {
6 | enable = true;
7 |
8 | permitRootLogin = "no";
9 |
10 | # Only pubkey auth
11 | passwordAuthentication = false;
12 | challengeResponseAuthentication = false;
13 | };
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/services/tinc.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | let secrets = import ../secrets.nix;
4 | in
5 | {
6 | disabledModules = [ "services/networking/tinc.nix" ];
7 |
8 | imports = [ ../pkgs/tinc/default.nix ];
9 |
10 | services.tinc.networks."darknet" = {
11 | interfaceType = "tap";
12 | chroot = true;
13 |
14 | hosts = secrets.tincHosts;
15 |
16 | extraConfig = ''
17 | PriorityInheritance = yes
18 | ProcessPriority = high
19 | Compression = 10
20 |
21 | ConnectTo = yeahnah
22 | ConnectTo = yeahnah
23 | '';
24 | };
25 |
26 | networking.firewall.allowedUDPPorts = [ yeah ];
27 | networking.firewall.allowedTCPPorts = [ nah ];
28 | }
29 |
--------------------------------------------------------------------------------
/services/xrdp.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 |
3 | {
4 | services.xrdp.enable = true;
5 | services.xrdp.defaultWindowManager = "${pkgs.i3-gaps}/bin/i3";
6 | }
--------------------------------------------------------------------------------
/users/ghuntley.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 | with lib;
3 |
4 | let secrets = import ../secrets.nix;
5 | in
6 | {
7 | # Define a user account. Don't forget to set a password with ‘passwd’.
8 | users.extraUsers.yeahnah = {
9 | description = "Geoffrey Huntley";
10 | group = "nah";
11 | extraGroups = [
12 | "audio"
13 | "libvirtd"
14 | "networkmanager"
15 | "users"
16 | "vboxusers"
17 | "video"
18 | "wheel"
19 | ];
20 |
21 | uid = 1000;
22 |
23 | createHome = true;
24 | home = "/home/yeahnah";
25 | shell = "/run/current-system/sw/bin/zsh";
26 |
27 | openssh.authorizedKeys.keys = secrets.sshKeys.yeah;
28 |
29 | };
30 | users.extraGroups.yeahnah.gid = 1000;
31 |
32 | system.activationScripts =
33 | {
34 | # Configure various dotfiles.
35 | dotfiles = stringAfter [ "users" ]
36 | ''
37 | cd /home/yeahnah
38 | '';
39 | };
40 | }
41 |
--------------------------------------------------------------------------------