This commit is contained in:
randomuser 2024-01-24 23:09:02 -06:00
commit 122a6adedb
17 changed files with 339 additions and 124 deletions

View File

@ -16,9 +16,9 @@ installation
`sudo nixos-rebuild --flake .#your-flake-name-here switch` `sudo nixos-rebuild --flake .#your-flake-name-here switch`
if you're trying to install `virtbox`, then use the `--impure` flag: if you're trying to install `netbox`, then use the `--impure` flag:
`sudo nixos-rebuild --flake .#virtbox switch --impure` `sudo nixos-rebuild --flake .#netbox switch --impure`
for alternate installations on non-NixOS hosts, a Makefile will be made available for alternate installations on non-NixOS hosts, a Makefile will be made available
@ -28,6 +28,8 @@ things to do
- integrate `disko` and `sops-nix` into the setup - integrate `disko` and `sops-nix` into the setup
- switch from gitea to cgit - switch from gitea to cgit
- establish backup infrastructure for `netbox` - establish backup infrastructure for `netbox`
- move gmail-mail-bridge into mail-sync repo
* (perhaps figure out how to produce a flake for it)
license license
------- -------

View File

@ -2,11 +2,8 @@
{ {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
./server.nix
../../modules/bootstrap.nix ../../modules/bootstrap.nix
../../modules/common.nix ../../modules/common.nix
../../modules/x11.nix
../../modules/discord.nix
]; ];
boot.loader.grub.enable = true; boot.loader.grub.enable = true;
@ -26,20 +23,40 @@
"; ";
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
vscodium-fhs neovim
libreoffice git
curl
];
anki-bin services.home-assistant = {
ytfzf enable = true;
kdenlive extraComponents = [
libreoffice # Components required to complete the onboarding
i3 "netgear"
gcc "hue"
gnumake "nest"
"esphome"
"met"
"radio_browser"
];
config = {
# Includes dependencies for a basic setup
# https://www.home-assistant.io/integrations/default_config/
default_config = {};
};
openFirewall = true;
};
scrcpy services.openssh = {
thunderbird enable = true;
mepo settings = {
PermitRootLogin = "no";
PasswordAuthentication = false;
};
};
users.users.usr.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKbhM3wj0oqjR3pUaZgpfX4Xo4dlzvBTbQ48zHyg7Pwx usr"
]; ];
system.stateVersion = "23.11"; system.stateVersion = "23.11";

View File

@ -5,27 +5,28 @@
{ {
imports = imports =
[ (modulesPath + "/profiles/qemu-guest.nix") [ (modulesPath + "/installer/scan/not-detected.nix")
]; ];
boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "sr_mod" "virtio_blk" ]; boot.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usbhid" "usb_storage" "ums_realtek" "sd_mod" ];
boot.initrd.kernelModules = [ ]; boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ]; boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ]; boot.extraModulePackages = [ ];
fileSystems."/" = fileSystems."/" =
{ device = "/dev/disk/by-uuid/7b70ab88-296c-4737-90b2-267cb2432dc1"; { device = "/dev/disk/by-uuid/948aeaf8-cb7e-4f85-ae3e-1bc6a25ec156";
fsType = "ext4"; fsType = "ext4";
}; };
swapDevices = [ ]; fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/617cb1ae-a788-429a-b0d4-63d46d8a4e1b";
fsType = "ext4";
};
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking swapDevices =
# (the default) this is the recommended approach. When using systemd-networkd it's [ { device = "/dev/disk/by-uuid/d82ae76c-68f4-4e70-9162-5dab5f84375b"; }
# still possible to use this option, but it's recommended to use it in conjunction ];
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp1s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
} }

View File

@ -1,9 +0,0 @@
{ lib, inputs, config, pkgs, home, ... }:
{
imports = [
../../home/x11.nix
];
home.stateVersion = "23.11";
}

View File

@ -1,70 +0,0 @@
{ lib, config, pkgs, ...}:
{
services.paperless = {
enable = true;
passwordFile = "/etc/paperless-password";
port = 3004;
address = "localhost";
extraConfig = {
PAPERLESS_URL = "https://paperless.beepboop.systems";
};
};
services.calibre-web.enable = true;
services.calibre-web.listen.port = 8080;
powerManagement.enable = false;
programs.adb.enable = true;
users.users.usr.extraGroups = ["adbusers"];
services.openssh = {
enable = true;
ports = [2222];
};
<<<<<<< Updated upstream
services.radicale = {
enable = true;
settings = {
auth = {
type = "htpasswd";
htpasswd_filename = "radicale-passwd";
htpasswd_encryption = "plain";
};
};
};
=======
>>>>>>> Stashed changes
systemd.targets.sleep.enable = false;
systemd.targets.suspend.enable = false;
systemd.targets.hibernate.enable = false;
systemd.targets.hybrid-sleep.enable = false;
systemd.services.paperless-web-bridge = {
script = ''
${pkgs.openssh}/bin/ssh -v -NR 3004:localhost:3004 -oExitOnForwardFailure=yes -p 55555 useracc@beepboop.systems
'';
wantedBy = [ "multi-user.target" ];
after = [ "network.target" "ankisyncd.service" ];
serviceConfig = {
Restart = "on-failure";
StartLimitBurst = 10000;
RestartSec = "0s";
};
};
systemd.services.internal-ssh-bridge = {
script = ''
${pkgs.openssh}/bin/ssh -v -NR 2222:localhost:2222 -oExitOnForwardFailure=yes -p 55555 useracc@beepboop.systems
'';
wantedBy = [ "multi-user.target" ];
after = [ "network.target" "ankisyncd.service" ];
serviceConfig = {
Restart = "on-failure";
StartLimitBurst = 10000;
RestartSec = "0s";
};
};
}

View File

@ -2,8 +2,9 @@
{ {
imports = [ imports = [
# ./hardware-configuration.nix ./hardware-configuration.nix
./nvidia.nix ./nvidia.nix
../../modules/ssh-phone-home.nix
../../modules/bootstrap.nix ../../modules/bootstrap.nix
../../modules/common.nix ../../modules/common.nix
../../modules/x11.nix ../../modules/x11.nix
@ -28,6 +29,16 @@
minetest minetest
]; ];
services.openssh.enable = true;
services.ssh-phone-home = {
enable = true;
localUser = "usr";
remoteHostname = "192.168.1.100";
remotePort = 22;
remoteUser = "usr";
bindPort = 2222;
};
boot.loader = { boot.loader = {
efi = { efi = {
canTouchEfiVariables = true; canTouchEfiVariables = true;

View File

@ -113,6 +113,7 @@ in {
[ [
./hardware-configuration.nix ./hardware-configuration.nix
../../modules/bootstrap.nix ../../modules/bootstrap.nix
../../builds/gmail_mail_bridge.nix
]; ];
networking.networkmanager.enable = true; networking.networkmanager.enable = true;
@ -136,11 +137,30 @@ in {
neovim neovim
]; ];
services.gmail_mail_bridge.enable = true;
system.copySystemConfiguration = true; system.copySystemConfiguration = true;
system.stateVersion = "23.05"; # don't change this, lol system.stateVersion = "23.05"; # don't change this, lol
boot.loader.grub.enable = true; boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/vda"; boot.loader.grub.device = "/dev/vda";
services.sslh = {
enable = true;
settings.protocols = [
{
host = "localhost";
name = "ssh";
port = "55555";
service = "ssh";
}
{
host = "localhost";
name = "tls";
port = "442";
}
];
};
# cgit # cgit
users = { users = {
groups.git = { }; groups.git = { };
@ -226,12 +246,10 @@ in {
''; '';
}; };
users.users.useracc = {
isNormalUser = true;
extraGroups = [ "wheel" "docker" ];
};
users.users.ryan = { users.users.ryan = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKbhM3wj0oqjR3pUaZgpfX4Xo4dlzvBTbQ48zHyg7Pwx usr"
];
isNormalUser = true; isNormalUser = true;
extraGroups = [ "wheel" "docker" ]; extraGroups = [ "wheel" "docker" ];
}; };
@ -278,6 +296,7 @@ in {
services.nginx.enable = true; services.nginx.enable = true;
services.nginx.clientMaxBodySize = "100m"; services.nginx.clientMaxBodySize = "100m";
services.nginx.defaultSSLListenPort = 442;
services.nginx.virtualHosts."beepboop.systems" = { services.nginx.virtualHosts."beepboop.systems" = {
forceSSL = true; forceSSL = true;
@ -319,6 +338,21 @@ in {
return 301 https://mail.beepboop.systems; return 301 https://mail.beepboop.systems;
''; '';
}; };
locations."~ \\.git" = {
extraConfig = ''
client_max_body_size 0;
include ${pkgs.nginx}/conf/fastcgi_params;
fastcgi_param SCRIPT_FILENAME ${pkgs.git}/bin/git-http-backend;
fastcgi_param GIT_HTTP_EXPORT_ALL "";
fastcgi_param GIT_PROJECT_ROOT /var/lib/git;
fastcgi_param PATH_INFO $uri;
# Forward REMOTE_USER as we want to know when we are authenticated
fastcgi_param REMOTE_USER $remote_user;
fastcgi_pass unix:${config.services.fcgiwrap.socketAddress};
'';
};
locations."/" = { locations."/" = {
extraConfig = '' extraConfig = ''
include ${pkgs.nginx}/conf/fastcgi_params; include ${pkgs.nginx}/conf/fastcgi_params;
@ -412,11 +446,20 @@ in {
services.nginx.virtualHosts."mail.beepboop.systems" = { services.nginx.virtualHosts."mail.beepboop.systems" = {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
globalRedirect = "cube.beepboop.systems"; locations."/bridge-submit" = {
extraConfig = ''
proxy_pass http://localhost:8041;
'';
};
locations."/" = {
extraConfig = ''
return 301 https://cube.beepboop.systems;
'';
};
}; };
networking.firewall = { networking.firewall = {
enable = true; enable = true;
allowedTCPPorts = [ 5232 55555 22 80 443 ]; allowedTCPPorts = [ 80 443 ];
}; };
} }

View File

@ -0,0 +1,19 @@
{ lib, pkgs, config, ... }:
let
cfg = config.services.gmail_mail_bridge;
appEnv = pkgs.python3.withPackages (p: with p; [ waitress (callPackage ./gmail_mail_bridge/default.nix {}) ]);
in {
options.services.gmail_mail_bridge = {
enable = lib.mkEnableOption "Enable the gmail_mail_bridge";
};
config = lib.mkIf cfg.enable {
systemd.services.gmail_mail_bridge = {
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${appEnv}/bin/waitress-serve --port=8041 gmail_mail_bridge:app";
StandardOutput = "journal";
};
};
};
}

1
builds/gmail_mail_bridge/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
__pycache_/

View File

@ -0,0 +1,10 @@
synchronize email from gmail accounts whose OAuth access is heavily restricted
background
----------
my school district disabled external OAuth access to email, which is not cool. this script gets around this and creates a bridge so you can recieve emails from your school email.
do note that this is heavily unpolished and most definately insecure. there are some hardcoded credentials (which you can change, it just takes a little technical know-how)
have fun!

View File

@ -0,0 +1,20 @@
{ pkgs, pythonPackages ? (import <nixpkgs> {}).python3Packages }:
pythonPackages.buildPythonPackage {
name = "gmail_mail_bridge";
src = ./gmail_mail_bridge;
propagatedBuildInputs = [ pythonPackages.flask pkgs.system-sendmail ];
installPhase = ''
runHook preInstall
mkdir -p $out/${pythonPackages.python.sitePackages}
cp -r . $out/${pythonPackages.python.sitePackages}/gmail_mail_bridge
runHook postInstall
'';
shellHook = "export FLASK_APP=gmail_mail_bridge";
format = "other";
}

View File

@ -0,0 +1,37 @@
from flask import Flask
from flask import request
from flask import redirect
from flask import abort
import logging
import smtplib
import email
from subprocess import Popen, PIPE, STDOUT
pre_shared_secret = "amongus sussy imposter"
to = "ryan@beepboop.systems"
app = Flask(__name__)
def handle_post(request):
msg = email.message_from_string(request.form["payload"])
del msg["To"]
msg["To"] = to
if not msg["From"]:
msg["From"] = "unknown-sender@mail.beepboop.systems"
s = smtplib.SMTP('localhost')
s.send_message(msg)
s.quit()
@app.route("/bridge-submit", methods = ["GET", "POST"])
def testing():
if request.method == 'POST':
data = request.form
if data['auth'] == pre_shared_secret:
handle_post(request)
else:
return 'you didn\'t use post'
return "default answer"

View File

@ -0,0 +1,12 @@
{ pkgs ? import (fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-23.11") {} }:
pkgs.mkShell {
packages = [
(pkgs.python3.withPackages (ps: [
ps.flask
]))
pkgs.curl
pkgs.jq
];
}

View File

@ -0,0 +1,23 @@
// google-side synchronization
// add a minute-wise trigger for mail synchronization
// go to the sidebar, select triggers, add a new one, configure it
// to run syncMail every minute
function syncMail() {
var threads = GmailApp.search("label:need_processing");
var label = GmailApp.getUserLabelByName("need_processing");
for (var thread of threads) {
for (var message of GmailApp.getMessagesForThread(thread)) {
var formData = {
auth: 'amongus sussy imposter',
payload: message.getRawContent(),
};
var options = {
'method' : 'POST',
'payload' : formData
};
var resp = UrlFetchApp.fetch('https://mail.beepboop.systems/bridge-submit', options);
}
thread.removeLabel(label);
}
}

View File

@ -209,12 +209,12 @@
}, },
"locked": { "locked": {
"lastModified": 1, "lastModified": 1,
"narHash": "sha256-Q/utpukYR3ZDNlXzUFtDrlmLDfusxdseH6THPh9JrQc=", "narHash": "sha256-3icKqIEjS068WDJ+05sEvFDL6DsPB0GpKTc8Bm4F9Po=",
"path": "/nix/store/6c7g2njv4c637rnhc7vxqvk9xcbq9ghf-source/builds", "path": "/nix/store/9797g0387xqz764w22ascnvn3bvm90kd-source/builds",
"type": "path" "type": "path"
}, },
"original": { "original": {
"path": "/nix/store/6c7g2njv4c637rnhc7vxqvk9xcbq9ghf-source/builds", "path": "/nix/store/9797g0387xqz764w22ascnvn3bvm90kd-source/builds",
"type": "path" "type": "path"
} }
}, },

View File

@ -82,13 +82,6 @@
specialArgs = { inherit inputs; }; specialArgs = { inherit inputs; };
modules = [ modules = [
./boxes/mainsail ./boxes/mainsail
home-manager.nixosModules.home-manager {
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.extraSpecialArgs = { inherit inputs; };
home-manager.users.usr = import ./boxes/mainsail/home.nix;
}
]; ];
}; };
}; };

105
modules/ssh-phone-home.nix Normal file
View File

@ -0,0 +1,105 @@
{ config, lib, pkgs, ... }:
# with thanks to
# https://www.auntieneo.net/2014/12/14/reverse-ssh-tunnel-on-nixos-with-systemd/
with lib;
let
inherit (pkgs) openssh;
cfg = config.services.ssh-phone-home;
in
{
###### interface
options = {
services.ssh-phone-home = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable a "phone home" reverse SSH proxy.
'';
};
persist = mkOption {
type = types.bool;
default = true;
description = ''
When this is set to true, the service will persistently attempt to
reconnect at intervals whenever the port forwarding operation fails.
This is the recommended behavior for reliable operation. If one finds
oneself in an environment where this kind of behavior might draw the
suspicion of a network administrator, it might be a good idea to
set this option to false (or not use <literal>ssh-phone-home</literal>
at all).
'';
};
localUser = mkOption {
description = ''
Local user to connect as (i.e. the user with password-less SSH keys).
'';
};
remoteHostname = mkOption {
description = ''
The remote host to connect to. This should be the host outside of the
firewall or NAT.
'';
};
remotePort = mkOption {
default = 22;
description = ''
The port on which to connect to the remote host via SSH protocol.
'';
};
remoteUser = mkOption {
description = ''
The username to connect to the remote host as.
'';
};
bindPort = mkOption {
default = 2222;
description = ''
The port to bind and listen to on the remote host.
'';
};
};
};
###### implementation
config = mkIf cfg.enable {
systemd.services.ssh-phone-home =
{
description = ''
Reverse SSH tunnel as a service
'';
# FIXME: This isn't triggered until a reboot, and probably won't work between suspends.
wantedBy = [ "multi-user.target" ];
serviceConfig = with cfg; {
User = cfg.localUser;
} // (if cfg.persist then
{
# Restart every 10 seconds on failure
RestartSec = 10;
Restart = "on-failure";
}
else {}
);
script = with cfg; ''
${openssh}/bin/ssh -NTC -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes -R ${toString bindPort}:localhost:22 -l ${remoteUser} -p ${toString remotePort} ${remoteHostname}
'';
};
};
}