From 7438942f9148ae5594de75d30fb3b18ed6e84023 Mon Sep 17 00:00:00 2001 From: Mikhail Klementev Date: Fri, 31 May 2019 00:02:30 +0000 Subject: [PATCH] Initial --- .gitignore | 3 ++ LICENSE | 21 ++++++++++ README.md | 15 ++++++++ configuration.nix | 53 ++++++++++++++++++++++++++ desktop.nix | 88 ++++++++++++++++++++++++++++++++++++++++++ hacks.nix | 31 +++++++++++++++ networking.nix | 70 ++++++++++++++++++++++++++++++++++ packages.nix | 97 +++++++++++++++++++++++++++++++++++++++++++++++ security.nix | 50 ++++++++++++++++++++++++ suspend.nix | 71 ++++++++++++++++++++++++++++++++++ 10 files changed, 499 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 configuration.nix create mode 100644 desktop.nix create mode 100644 hacks.nix create mode 100644 networking.nix create mode 100644 packages.nix create mode 100644 security.nix create mode 100644 suspend.nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6accb2c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +hardware-configuration.nix +wireless-networks.nix +secrets.nix diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e45c9b4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Mikhail Klementev + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..46aea1d --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# localhost + +## Installation + + parted... + cryptsetup... + mount... + + nix-env -iA nixos.gitMinimal + git clone https://code.dumpstack.io/infra/localhost.git /mnt/etc/nixos/ + + nixos-generate-config --root /mnt + + nixos-install + reboot diff --git a/configuration.nix b/configuration.nix new file mode 100644 index 0000000..644c6a3 --- /dev/null +++ b/configuration.nix @@ -0,0 +1,53 @@ +# nix-channel --add https://nixos.org/channels/nixos-19.03 nixos +# nix-channel --add https://nixos.org/channels/nixos-unstable unstable +# nix-channel --update +# +{ config, pkgs, ... }: + +let + unstable = import {}; +in { + imports = + [ + ./hardware-configuration.nix + ./packages.nix + ./networking.nix + ./desktop.nix + ./security.nix + ./hacks.nix + ]; + + time.timeZone = "UTC"; + + boot.kernelPackages = pkgs.linuxPackages; + + i18n = { + consoleFont = "latarcyrheb-sun32"; + consoleKeyMap = "us"; + defaultLocale = "en_US.UTF-8"; + }; + + swapDevices = [ + { device = "/var/swapfile"; + size = 32768; # MiB + } + ]; + + users.users.root.shell = pkgs.zsh; + users.users.user = { + isNormalUser = true; + shell = pkgs.zsh; + extraGroups = [ "wheel" "audio" "libvirtd" ]; + }; + + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + boot.tmpOnTmpfs = true; + + system.stateVersion = "19.03"; + system.autoUpgrade.enable = true; + + nix.optimise.automatic = true; + nix.gc.automatic = true; + nix.gc.options = "--delete-older-than 7d"; +} diff --git a/desktop.nix b/desktop.nix new file mode 100644 index 0000000..219e08a --- /dev/null +++ b/desktop.nix @@ -0,0 +1,88 @@ +{ config, pkgs, ... }: + +{ + services.xserver.enable = true; + services.xserver.layout = "us,ru"; + services.xserver.xkbOptions = "ctrl:nocaps,grp:rctrl_toggle"; + services.xserver.videoDrivers = [ "nvidia" ]; + services.xserver.windowManager.xmonad.enable = true; + services.xserver.windowManager.xmonad.enableContribAndExtras = true; + + programs.dconf.enable = true; + programs.light.enable = true; + + hardware.opengl.extraPackages = [ pkgs.vaapiVdpau ]; + + sound.enable = true; + hardware.pulseaudio.enable = true; + + environment.variables = { + GDK_SCALE = "2"; + GDK_DPI_SCALE = "0.4"; + }; + + fonts = { + enableFontDir = true; + enableGhostscriptFonts = true; + fonts = with pkgs; [ + ubuntu_font_family + ]; + }; + + environment.etc."X11/xorg.conf.d/60-trackball.conf".text = '' + Section "InputClass" + Identifier "Marble Mouse" + MatchProduct "Logitech USB Trackball" + MatchIsPointer "on" + MatchDevicePath "/dev/input/event*" + Driver "evdev" + + Option "ButtonMapping" "3 8 1 4 5 6 7 2 2" + Option "EmulateWheel" "true" + Option "EmulateWheelButton" "9" + Option "EmulateWheelInertia" "10" + Option "ZAxisMapping" "4 5" + Option "Emulate3Buttons" "true" + EndSection + ''; + + environment.etc."X11/xorg.conf.d/61-trackpoint.conf".text = '' + Section "InputClass" + Identifier "Trackpoint Wheel Emulation" + Driver "evdev" + MatchProduct "TPPS/2 Elan TrackPoint" + MatchDevicePath "/dev/input/event*" + + Option "EmulateWheel" "true" + Option "EmulateWheelButton" "2" + Option "Emulate3Buttons" "false" + Option "XAxisMapping" "6 7" + Option "YAxisMapping" "4 5" + Option "Device Accel Constant Deceleration" "0.5" + EndSection + ''; + + services.xserver.displayManager.lightdm = { + background = "black"; + greeters.mini = { + enable = true; + user = "user"; + }; + }; + + programs.chromium = { + enable = true; + extensions = [ + "cjpalhdlnbpafiamejdnhcphjbkeiagm" # uBlock Origin + "gcbommkclmclpchllfjekcdonpmejbdp" # HTTPS Everywhere + "pkehgijcmpdhfbdbbnkijodmdjhbjlgp" # Privacy Badger + "dbepggeogbaibhgnhhndojpepiihcmeb" # Vimium + "aapbdbdomjkkjkaonfhkkikfgjllcleb" # Google Translate + "naepdomgkenhinolocfifgehidddafch" # Browserpass + ]; + }; + + networking.localCommands = '' + mkdir -p /tmp/chromium && chown user:users /tmp/chromium + ''; +} diff --git a/hacks.nix b/hacks.nix new file mode 100644 index 0000000..18f14b1 --- /dev/null +++ b/hacks.nix @@ -0,0 +1,31 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./suspend.nix ]; + + services.batteryNotifier = { # suspend.nix + enable = true; + notifyCapacity = 20; + suspendCapacity = 10; + }; + + boot.kernel.sysctl."net.ipv4.ip_default_ttl" = 65; + + systemd = { + services = { + "sid-chroot-mounts" = { + enable = true; + description = "Setup mounts for debian sid chroot"; + wantedBy = [ "multi-user.target" ]; + script = '' + ls /home/user/chroots/sid-root/home/user/.zshrc && exit + ${pkgs.utillinux}/bin/mount --bind /home/user /home/user/chroots/sid-root/home/user + ${pkgs.utillinux}/bin/mount --bind /dev /home/user/chroots/sid-root/dev + ${pkgs.utillinux}/bin/mount --bind /proc /home/user/chroots/sid-root/proc + ${pkgs.utillinux}/bin/mount --bind /sys /home/user/chroots/sid-root/sys + ''; + serviceConfig.Type = "oneshot"; + }; + }; + }; +} diff --git a/networking.nix b/networking.nix new file mode 100644 index 0000000..9f99ce3 --- /dev/null +++ b/networking.nix @@ -0,0 +1,70 @@ +{ config, pkgs, ... }: + +let + secrets = import ./secrets.nix; +in { + networking.hostName = "local"; + networking.nameservers = [ "1.1.1.1" ]; + + networking.wireless.enable = true; + imports = [ ./wireless-networks.nix ]; + + networking.firewall = { + enable = true; + extraCommands = '' + iptables -F OUTPUT + iptables -P OUTPUT DROP + + iptables -A OUTPUT -o lo+ -j ACCEPT + iptables -A OUTPUT -o vpn+ -j ACCEPT + iptables -A OUTPUT -o tun+ -j ACCEPT + iptables -A OUTPUT -o tap+ -j ACCEPT + iptables -A OUTPUT -o veth+ -j ACCEPT + iptables -A OUTPUT -o vnet+ -j ACCEPT + iptables -A OUTPUT -o docker+ -j ACCEPT + iptables -A OUTPUT -o virbr+ -j ACCEPT + iptables -A OUTPUT -o virbr0-nic -j ACCEPT + + # iptables -A OUTPUT -d 192.0.2.17 -j ACCEPT + ${secrets.iptables} + ''; + checkReversePath = false; + }; + + services.openvpn.servers.vpn = { + autoStart = true; + config = secrets.vpn-config; + authUserPass.username = secrets.vpn-username; + authUserPass.password = secrets.vpn-password; + updateResolvConf = true; + }; + + systemd = { + services = { + "macchanger" = { + description = "Changes MAC of all interfaces for privacy reasons"; + wants = [ "network-pre.target" ]; + wantedBy = [ "multi-user.target" ]; + before = [ "network-pre.target" ]; + bindsTo = [ "sys-subsystem-net-devices-wlp0s20f3.device" ]; + after = [ "sys-subsystem-net-devices-wlp0s20f3.device" ]; + # we always return true to avoid errors while 'nixos-rebuild switch' + # because it does not stop interfaces + # TODO it must be changed to work only when system starts + script = '' + ${pkgs.macchanger}/bin/macchanger -e wlp0s20f3 || true + ${pkgs.macchanger}/bin/macchanger -e enp0s31f6 || true + ''; + serviceConfig.Type = "oneshot"; + }; + "openvpn-restart-after-suspend" = { + description = "Restart OpenVPN after suspend"; + after = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ]; + wantedBy = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ]; + script = '' + ${pkgs.systemd}/bin/systemctl try-restart openvpn-vpn.service + ''; + }; + }; + }; +} diff --git a/packages.nix b/packages.nix new file mode 100644 index 0000000..cca171e --- /dev/null +++ b/packages.nix @@ -0,0 +1,97 @@ +{ config, pkgs, ... }: + +let + unstable = import {}; +in { + nixpkgs.config.allowUnfree = true; + + programs.zsh.enable = true; + programs.browserpass.enable = true; + programs.adb.enable = true; + + programs.java = { + enable = true; + package = unstable.pkgs.jdk11; + }; + + services.ntp.enable = true; + services.tlp.enable = true; + services.vnstat.enable = true; + + virtualisation.docker.enable = true; + + virtualisation.libvirtd = { + enable = true; + qemuVerbatimConfig = '' + namespaces = [] + user = "user" + group = "users" + ''; + }; + + environment.systemPackages = with pkgs; [ + # nix + patchelfUnstable nix-index + appimage-run + + # gpu + nvtop cudatoolkit_10 + + # utils + wget tmux zsh vim emacs htop acpi bc p7zip mpv + git pass unzip zip w3m whois dnsutils feh + parted iotop nmap tldr sshfs pinentry_ncurses + oathToolkit neomutt pciutils easyrsa openvpn + lsof tcpdump ddcutil pmount woeusb tigervnc + file mkpasswd irssi heroku hdparm debootstrap + proot fakeroot fakechroot lm_sensors powertop + exfat traceroute graphicsmagick-imagemagick-compat + pdftk vnstat dunst ghostscript graphicsmagick + browsh + + # gpg-related + gnupg unstable.yubikey-manager unstable.yubikey-personalization + + # virtualization + nixops + kvm + virtmanager + virtviewer + spice + spice-gtk + + # python + python2Full + python2Packages.obfsproxy + + python3Full + python3Packages.ipython + + # dev + go gnumake gcc clang clang-analyzer global + maven binutils-unwrapped openssl bison flex fop libxslt + cmake manpages unstable.gradle cargo rustc guile + + # re + radare2 radare2-cutter + + # x render + vdpauinfo + + # base x + rofi xlibs.xmodmap ubuntu_font_family i3lock unstable.kitty + xfce.xfce4notifyd libnotify gtk_engines x2x lxappearance-gtk3 + pulsemixer arc-theme xorg.xhost xclip + gnome3.dconf gnome3.dconf-editor gsettings-desktop-schemas gsettings-qt + xorg.xcursorthemes capitaine-cursors + + # x apps + unstable.chromium escrotum unstable.wire-desktop tdesktop ssvnc tightvnc + quaternion veracrypt evince krita gimp gnome3.gnome-maps + android-file-transfer darktable xournal gnome3.eog audacious audacity + matrique libreoffice electrum adobe-reader unstable.wireshark lmms + unstable.firefox + + (pkgs.writeShellScriptBin "virt-manager-unstable" "${unstable.virtmanager}/bin/virt-manager $@") + ]; +} diff --git a/security.nix b/security.nix new file mode 100644 index 0000000..71f5afe --- /dev/null +++ b/security.nix @@ -0,0 +1,50 @@ +{ config, pkgs, ... }: + +{ + security.allowUserNamespaces = true; + security.allowSimultaneousMultithreading = true; + security.lockKernelModules = false; + + programs.ssh.startAgent = false; + programs.gnupg = { + agent.enable = true; + agent.enableSSHSupport = true; + agent.enableExtraSocket = true; + agent.enableBrowserSocket = true; + dirmngr.enable = true; + }; + + # Bus 001 Device 002: ID 1050:0404 Yubico.com Yubikey 4 CCID + services.udev = { + extraRules = '' + ACTION=="add|change", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0404", MODE="0666" + ''; + }; + + systemd = { + services = { + "force-lock-after-suspend" = { + serviceConfig.User = "user"; + description = "Force i3lock after suspend"; + before = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ]; + wantedBy = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ]; + script = '' + DISPLAY=:0 ${pkgs.i3lock}/bin/i3lock -n -c 000000 + ''; + }; + }; + }; + + # Allow manage backlight without sudo + security.sudo = { + enable = true; + extraConfig = '' + %wheel ALL=(ALL:ALL) NOPASSWD: ${pkgs.light}/bin/light + ''; + }; + + security.wrappers = { + pmount.source = "${pkgs.pmount}/bin/pmount"; + pumount.source = "${pkgs.pmount}/bin/pumount"; + }; +} diff --git a/suspend.nix b/suspend.nix new file mode 100644 index 0000000..f67974a --- /dev/null +++ b/suspend.nix @@ -0,0 +1,71 @@ +# https://gist.github.com/domenkozar/82886ee82efee623cdc0d19eb81c7fb7 + +{ config, lib, pkgs, ...}: + +with lib; + +let + cfg = config.services.batteryNotifier; +in { + options = { + services.batteryNotifier = { + enable = mkOption { + default = false; + description = '' + Whether to enable battery notifier. + ''; + }; + device = mkOption { + default = "BAT0"; + description = '' + Device to monitor. + ''; + }; + notifyCapacity = mkOption { + default = 10; + description = '' + Battery level at which a notification shall be sent. + ''; + }; + suspendCapacity = mkOption { + default = 5; + description = '' + Battery level at which a suspend unless connected shall be sent. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.user.timers."lowbatt" = { + description = "check battery level"; + timerConfig.OnBootSec = "1m"; + timerConfig.OnUnitInactiveSec = "1m"; + timerConfig.Unit = "lowbatt.service"; + wantedBy = ["timers.target"]; + }; + systemd.user.services."lowbatt" = { + description = "battery level notifier"; + serviceConfig.PassEnvironment = "DISPLAY"; + script = '' + export battery_capacity=$(${pkgs.coreutils}/bin/cat /sys/class/power_supply/${cfg.device}/capacity) + export battery_status=$(${pkgs.coreutils}/bin/cat /sys/class/power_supply/${cfg.device}/status) + + if [[ $battery_capacity -le ${builtins.toString cfg.notifyCapacity} && $battery_status = "Discharging" ]]; then + ${pkgs.libnotify}/bin/notify-send --urgency=critical --hint=int:transient:1 --icon=battery_empty "Battery Low" "You should probably plug-in." + fi + + if [[ $battery_capacity -le ${builtins.toString cfg.suspendCapacity} && $battery_status = "Discharging" ]]; then + ${pkgs.libnotify}/bin/notify-send --urgency=critical --hint=int:transient:1 --icon=battery_empty "Battery Critically Low" "Computer will suspend in 60 seconds." + sleep 60s + + battery_status=$(${pkgs.coreutils}/bin/cat /sys/class/power_supply/${cfg.device}/status) + if [[ $battery_status = "Discharging" ]]; then + #systemctl suspend + systemctl poweroff + fi + fi + ''; + }; + }; +}