Compare commits
3 commits
14ec1eca2e
...
6c60161d1a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c60161d1a | ||
|
|
ec5edefad8 | ||
|
|
b3a36d9dbe |
6 changed files with 182 additions and 17 deletions
|
|
@ -57,6 +57,7 @@
|
||||||
|
|
||||||
mkSharedModules = pkgs: pkgs-unstable: [
|
mkSharedModules = pkgs: pkgs-unstable: [
|
||||||
./nixos/modules/base.nix
|
./nixos/modules/base.nix
|
||||||
|
./nixos/modules/services/wireguard-peer.nix
|
||||||
inputs.home-manager.nixosModules.home-manager
|
inputs.home-manager.nixosModules.home-manager
|
||||||
({ ... }: {
|
({ ... }: {
|
||||||
home-manager.useGlobalPkgs = true;
|
home-manager.useGlobalPkgs = true;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
{ pkgs, ... }:
|
{ pkgs, repoRoot, ... }:
|
||||||
let
|
let
|
||||||
commands = import ../../../../lib/commands.nix { inherit pkgs; };
|
commands = import ../../../../lib/commands.nix { inherit pkgs; };
|
||||||
inherit (commands) uwsm term;
|
inherit (commands) uwsm term;
|
||||||
height = 20;
|
height = 20;
|
||||||
|
wireguardToggle = "${pkgs.xonsh}/bin/xonsh ${repoRoot}/util/toggle_wg.xsh";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
|
@ -35,11 +36,12 @@ in
|
||||||
};
|
};
|
||||||
"modules" = [
|
"modules" = [
|
||||||
"clock"
|
"clock"
|
||||||
|
"idle_inhibitor"
|
||||||
"sway/language"
|
"sway/language"
|
||||||
"network"
|
"network"
|
||||||
|
"custom/wireguard"
|
||||||
"bluetooth"
|
"bluetooth"
|
||||||
"pulseaudio"
|
"pulseaudio"
|
||||||
"idle_inhibitor"
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
"sway/workspaces" = {
|
"sway/workspaces" = {
|
||||||
|
|
@ -53,7 +55,7 @@ in
|
||||||
spacing = 8;
|
spacing = 8;
|
||||||
};
|
};
|
||||||
idle_inhibitor = {
|
idle_inhibitor = {
|
||||||
format = "| {icon}";
|
format = "| {icon} ";
|
||||||
start-activated = true;
|
start-activated = true;
|
||||||
format-icons = {
|
format-icons = {
|
||||||
activated = "🫨";
|
activated = "🫨";
|
||||||
|
|
@ -61,7 +63,8 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"sway/language" = {
|
"sway/language" = {
|
||||||
format = "| {short}";
|
# this one gobbles all trailing ascii whitespace for some reason. use this unicode instead
|
||||||
|
format = "| {short} ";
|
||||||
tooltip-format = "{long}";
|
tooltip-format = "{long}";
|
||||||
};
|
};
|
||||||
clock = {
|
clock = {
|
||||||
|
|
@ -72,29 +75,36 @@ in
|
||||||
};
|
};
|
||||||
battery = {
|
battery = {
|
||||||
interval = 60;
|
interval = 60;
|
||||||
format = "| {capacity}%";
|
format = "| {capacity}% ";
|
||||||
format-charging = "| ch:{capacity}%";
|
format-charging = "| ch:{capacity}% ";
|
||||||
};
|
};
|
||||||
network = {
|
network = {
|
||||||
tooltip-format = "{ifname} = {ipaddr}/{cidr}";
|
tooltip-format = "{ifname} = {ipaddr}/{cidr}";
|
||||||
format-wifi = "| w:{ipaddr}";
|
format-wifi = "| w:{essid} ";
|
||||||
format-ethernet = "| e:{ipaddr}";
|
format-ethernet = "| e:{ipaddr} ";
|
||||||
format-linked = "| l:{ipaddr}";
|
format-linked = "| l:{ipaddr} ";
|
||||||
format-disconnected = "| d";
|
format-disconnected = "| w:d ";
|
||||||
interval = 15;
|
interval = 15;
|
||||||
on-click = "${uwsm} ${term} -e nmtui";
|
on-click = "${uwsm} ${term} -e nmtui";
|
||||||
};
|
};
|
||||||
|
"custom/wireguard" = {
|
||||||
|
exec = "${wireguardToggle} status";
|
||||||
|
on-click = "${wireguardToggle} toggle";
|
||||||
|
format = "| wg:{text} ";
|
||||||
|
interval = 15;
|
||||||
|
tooltip = false;
|
||||||
|
};
|
||||||
bluetooth = {
|
bluetooth = {
|
||||||
format = "| bt:{num_connections}";
|
format = "| bt:{num_connections} ";
|
||||||
format-disabled = "";
|
format-disabled = "";
|
||||||
format-no-controller = "";
|
format-no-controller = "";
|
||||||
interval = 15;
|
interval = 15;
|
||||||
on-click = "${uwsm} ${term} -e bluetui";
|
on-click = "${uwsm} ${term} -e bluetui";
|
||||||
};
|
};
|
||||||
pulseaudio = {
|
pulseaudio = {
|
||||||
format = "| snd{volume}%";
|
format = "| snd{volume}% ";
|
||||||
format-muted = "| snd:-";
|
format-muted = "| snd:- ";
|
||||||
format-bluetooth = "| snd(bt):{volume}%";
|
format-bluetooth = "| snd(bt):{volume}% ";
|
||||||
on-click = "${uwsm} pavucontrol";
|
on-click = "${uwsm} pavucontrol";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{ lib, pkgs, modulesPath, ... }:
|
{ lib, pkgs, modulesPath, ... }:
|
||||||
let
|
let
|
||||||
forgejoDomain = "git.alisceon.com";
|
forgejoDomain = "git.alisceon.com";
|
||||||
forgejoRunnerTokenFile = "/var/lib/forgejo/runner_token";
|
syncthingDomain = "syncthing.alisceon.com";
|
||||||
|
|
||||||
fetchOciAuthorizedKeys = pkgs.writeShellApplication {
|
fetchOciAuthorizedKeys = pkgs.writeShellApplication {
|
||||||
name = "fetch-oci-authorized-keys";
|
name = "fetch-oci-authorized-keys";
|
||||||
|
|
@ -34,7 +34,7 @@ let
|
||||||
pkgs.util-linux
|
pkgs.util-linux
|
||||||
];
|
];
|
||||||
text = ''
|
text = ''
|
||||||
token_file=${lib.escapeShellArg forgejoRunnerTokenFile}
|
token_file=${lib.escapeShellArg "/var/lib/forgejo/runner_token"}
|
||||||
|
|
||||||
if [ -s "$token_file" ]; then
|
if [ -s "$token_file" ]; then
|
||||||
chmod 0600 "$token_file"
|
chmod 0600 "$token_file"
|
||||||
|
|
@ -69,8 +69,12 @@ in
|
||||||
22
|
22
|
||||||
80
|
80
|
||||||
443
|
443
|
||||||
|
22000
|
||||||
24601
|
24601
|
||||||
];
|
];
|
||||||
|
firewall.allowedUDPPorts = [
|
||||||
|
22000
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
boot = {
|
boot = {
|
||||||
|
|
@ -123,6 +127,32 @@ in
|
||||||
PermitRootLogin = lib.mkForce "prohibit-password";
|
PermitRootLogin = lib.mkForce "prohibit-password";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.syncthing = {
|
||||||
|
enable = true;
|
||||||
|
dataDir = "/var/lib/syncthing";
|
||||||
|
guiAddress = "127.0.0.1:8384";
|
||||||
|
openDefaultPorts = false;
|
||||||
|
overrideDevices = false;
|
||||||
|
overrideFolders = false;
|
||||||
|
settings = {
|
||||||
|
gui = {
|
||||||
|
insecureAdminAccess = false;
|
||||||
|
insecureSkipHostcheck = false;
|
||||||
|
};
|
||||||
|
options = {
|
||||||
|
globalAnnounceEnabled = false;
|
||||||
|
localAnnounceEnabled = false;
|
||||||
|
listenAddresses = [
|
||||||
|
"tcp://0.0.0.0:22000"
|
||||||
|
"quic://0.0.0.0:22000"
|
||||||
|
];
|
||||||
|
natEnabled = false;
|
||||||
|
relaysEnabled = false;
|
||||||
|
urAccepted = -1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
services.forgejo = {
|
services.forgejo = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.forgejo-lts;
|
package = pkgs.forgejo-lts;
|
||||||
|
|
@ -164,7 +194,7 @@ in
|
||||||
enable = true;
|
enable = true;
|
||||||
name = "alisceon-core-podman";
|
name = "alisceon-core-podman";
|
||||||
url = "https://${forgejoDomain}";
|
url = "https://${forgejoDomain}";
|
||||||
tokenFile = forgejoRunnerTokenFile;
|
tokenFile = "/var/lib/forgejo/runner_token";
|
||||||
labels = [
|
labels = [
|
||||||
"ubuntu-latest:docker://node:22-bookworm"
|
"ubuntu-latest:docker://node:22-bookworm"
|
||||||
"debian-latest:docker://node:22-bookworm"
|
"debian-latest:docker://node:22-bookworm"
|
||||||
|
|
@ -203,6 +233,24 @@ in
|
||||||
recommendedProxySettings = true;
|
recommendedProxySettings = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
${syncthingDomain} = {
|
||||||
|
serverName = syncthingDomain;
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:8384";
|
||||||
|
recommendedProxySettings = false;
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_set_header Host $proxy_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_read_timeout 600s;
|
||||||
|
proxy_send_timeout 600s;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -264,6 +312,28 @@ in
|
||||||
|
|
||||||
systemd.services.fetch-ssh-keys.enable = false;
|
systemd.services.fetch-ssh-keys.enable = false;
|
||||||
|
|
||||||
|
systemd.services.syncthing = {
|
||||||
|
serviceConfig = {
|
||||||
|
LockPersonality = true;
|
||||||
|
PrivateIPC = true;
|
||||||
|
ProcSubset = "pid";
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectHome = true;
|
||||||
|
ProtectProc = "invisible";
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ReadWritePaths = [ "/var/lib/syncthing" ];
|
||||||
|
RemoveIPC = true;
|
||||||
|
RestrictAddressFamilies = [
|
||||||
|
"AF_INET"
|
||||||
|
"AF_INET6"
|
||||||
|
"AF_NETLINK"
|
||||||
|
"AF_UNIX"
|
||||||
|
];
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
UMask = "0077";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
systemd.services.forgejo-runner-token = {
|
systemd.services.forgejo-runner-token = {
|
||||||
description = "Generate Forgejo runner registration token";
|
description = "Generate Forgejo runner registration token";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ in
|
||||||
|
|
||||||
security.sudo.wheelNeedsPassword = false;
|
security.sudo.wheelNeedsPassword = false;
|
||||||
|
|
||||||
|
alisceon.wireguardPeer.enable = true;
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
printing.enable = true;
|
printing.enable = true;
|
||||||
pulseaudio.enable = false;
|
pulseaudio.enable = false;
|
||||||
|
|
|
||||||
57
nixos/modules/services/wireguard-peer.nix
Normal file
57
nixos/modules/services/wireguard-peer.nix
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
{ config, lib, pkgs, repoLocalPath, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.alisceon.wireguardPeer;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.alisceon.wireguardPeer = {
|
||||||
|
enable = lib.mkEnableOption "a single WireGuard peer managed by wg-quick";
|
||||||
|
|
||||||
|
interface = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "wg0";
|
||||||
|
description = "WireGuard interface name.";
|
||||||
|
};
|
||||||
|
|
||||||
|
configFile = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/etc/wireguard/${cfg.interface}.conf";
|
||||||
|
defaultText = "/etc/wireguard/<interface>.conf";
|
||||||
|
description = ''
|
||||||
|
Path to an external wg-quick config file. Keep it root-owned and mode
|
||||||
|
0600 so private keys and peer material stay outside Git and the Nix store.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
autostart = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to bring the WireGuard interface up at boot.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = lib.hasPrefix "/" cfg.configFile;
|
||||||
|
message = "alisceon.wireguardPeer.configFile must be an absolute path outside the repo.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = !(lib.hasPrefix repoLocalPath cfg.configFile);
|
||||||
|
message = "alisceon.wireguardPeer.configFile must be outside ${repoLocalPath}.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.wg-quick.interfaces.${cfg.interface} = {
|
||||||
|
inherit (cfg) autostart configFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."wg-quick-${cfg.interface}".unitConfig.ConditionPathExists = cfg.configFile;
|
||||||
|
|
||||||
|
environment.systemPackages = [ pkgs.wireguard-tools ];
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d /etc/wireguard 0700 root root -"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
25
util/toggle_wg.xsh
Executable file
25
util/toggle_wg.xsh
Executable file
|
|
@ -0,0 +1,25 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
|
isup = "does not exist." not in $(ip link show dev wg0 2>&1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
match sys.argv[1]:
|
||||||
|
case "toggle":
|
||||||
|
if isup:
|
||||||
|
footclient wg-quick down wg0
|
||||||
|
else:
|
||||||
|
footclient wg-quick up wg0
|
||||||
|
case "status":
|
||||||
|
if isup:
|
||||||
|
print("u")
|
||||||
|
else:
|
||||||
|
print("d")
|
||||||
|
case _:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
except (RuntimeError, IndexError):
|
||||||
|
print('"toggle" or "status" must be provided')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
exit(0)
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue