mirror of
https://github.com/deltathetawastaken/dotfiles.git
synced 2025-12-06 07:16:37 +03:00
add app.nix + restrucruting
This commit is contained in:
parent
434bfe09e1
commit
5fda9bb420
149
derivations/chromium-gost.nix
Normal file
149
derivations/chromium-gost.nix
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
{ stdenv
|
||||||
|
, lib
|
||||||
|
, dpkg-deb
|
||||||
|
, fetchurl
|
||||||
|
, autoPatchelfHook
|
||||||
|
, wrapGAppsHook
|
||||||
|
, flac
|
||||||
|
, gnome2
|
||||||
|
, harfbuzzFull
|
||||||
|
, nss
|
||||||
|
, snappy
|
||||||
|
, xdg-utils
|
||||||
|
, xorg
|
||||||
|
, alsa-lib
|
||||||
|
, atk
|
||||||
|
, cairo
|
||||||
|
, cups
|
||||||
|
, curl
|
||||||
|
, dbus
|
||||||
|
, expat
|
||||||
|
, fontconfig
|
||||||
|
, freetype
|
||||||
|
, gdk-pixbuf
|
||||||
|
, glib
|
||||||
|
, gtk3
|
||||||
|
, libX11
|
||||||
|
, libxcb
|
||||||
|
, libXScrnSaver
|
||||||
|
, libXcomposite
|
||||||
|
, libXcursor
|
||||||
|
, libXdamage
|
||||||
|
, libXext
|
||||||
|
, libXfixes
|
||||||
|
, libXi
|
||||||
|
, libXrandr
|
||||||
|
, libXrender
|
||||||
|
, libXtst
|
||||||
|
, libdrm
|
||||||
|
, libnotify
|
||||||
|
, libopus
|
||||||
|
, libpulseaudio
|
||||||
|
, libuuid
|
||||||
|
, libxshmfence
|
||||||
|
, mesa
|
||||||
|
, nspr
|
||||||
|
, pango
|
||||||
|
, systemd
|
||||||
|
, at-spi2-atk
|
||||||
|
, at-spi2-core
|
||||||
|
, libqt5pas
|
||||||
|
, qt6
|
||||||
|
, vivaldi-ffmpeg-codecs
|
||||||
|
}:
|
||||||
|
|
||||||
|
|
||||||
|
stdenv.mkDerivation rec {
|
||||||
|
name = "chromium-gost";
|
||||||
|
version = "122.0.6261.128";
|
||||||
|
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/deemru/Chromium-Gost/releases/download/${version}/chromium-gost-${version}-linux-amd64.deb";
|
||||||
|
hash = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
dpkg-deb
|
||||||
|
autoPatchelfHook
|
||||||
|
qt6.wrapQtAppsHook
|
||||||
|
wrapGAppsHook
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
flac
|
||||||
|
harfbuzzFull
|
||||||
|
nss
|
||||||
|
snappy
|
||||||
|
xdg-utils
|
||||||
|
xorg.libxkbfile
|
||||||
|
alsa-lib
|
||||||
|
at-spi2-atk
|
||||||
|
at-spi2-core
|
||||||
|
atk
|
||||||
|
cairo
|
||||||
|
cups
|
||||||
|
curl
|
||||||
|
dbus
|
||||||
|
expat
|
||||||
|
fontconfig.lib
|
||||||
|
freetype
|
||||||
|
gdk-pixbuf
|
||||||
|
glib
|
||||||
|
gnome2.GConf
|
||||||
|
gtk3
|
||||||
|
libX11
|
||||||
|
libXScrnSaver
|
||||||
|
libXcomposite
|
||||||
|
libXcursor
|
||||||
|
libXdamage
|
||||||
|
libXext
|
||||||
|
libXfixes
|
||||||
|
libXi
|
||||||
|
libXrandr
|
||||||
|
libXrender
|
||||||
|
libXtst
|
||||||
|
libdrm
|
||||||
|
libnotify
|
||||||
|
libopus
|
||||||
|
libuuid
|
||||||
|
libxcb
|
||||||
|
libxshmfence
|
||||||
|
mesa
|
||||||
|
nspr
|
||||||
|
nss
|
||||||
|
pango
|
||||||
|
stdenv.cc.cc.lib
|
||||||
|
libqt5pas
|
||||||
|
qt6.qtbase
|
||||||
|
];
|
||||||
|
|
||||||
|
unpackPhase = ''
|
||||||
|
mkdir -p $TMP
|
||||||
|
mkdir -p $out/bin
|
||||||
|
mkdir -p $out/share
|
||||||
|
dpkg -x $src $TMP
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
cp -r $TMP/opt/chromium $out
|
||||||
|
cp -r $TMP/usr/share $out/share
|
||||||
|
substituteInPlace $out/share/applications/chromium-gost.desktop --replace /usr/ $out/
|
||||||
|
substituteInPlace $out/share/menu/chromium-gost --replace /opt/ $out/
|
||||||
|
substituteInPlace $out/share/gnome-control-center/default-apps/chromium-gost.xml --replace /opt/ $out/
|
||||||
|
'';
|
||||||
|
|
||||||
|
runtimeDependencies = map lib.getLib [
|
||||||
|
libpulseaudio
|
||||||
|
curl
|
||||||
|
systemd
|
||||||
|
vivaldi-ffmpeg-codecs
|
||||||
|
] ++ buildInputs;
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Chromium Fork with GOST support";
|
||||||
|
homepage = "https://www.cryptopro.ru/products/chromium-gost";
|
||||||
|
license = licenses.unfree;
|
||||||
|
maintainers = with maintainers; [];
|
||||||
|
platforms = [ "x86_64-linux" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -4,14 +4,6 @@
|
||||||
home.username = "delta";
|
home.username = "delta";
|
||||||
home.stateVersion = "23.11";
|
home.stateVersion = "23.11";
|
||||||
|
|
||||||
home.pointerCursor = {
|
|
||||||
gtk.enable = true;
|
|
||||||
x11.enable = true;
|
|
||||||
package = pkgs.bibata-cursors;
|
|
||||||
name = "Bibata-Modern-Classic";
|
|
||||||
size = 16;
|
|
||||||
};
|
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
./programs
|
./programs
|
||||||
./theme.nix
|
./theme.nix
|
||||||
|
|
@ -42,46 +34,6 @@
|
||||||
# };
|
# };
|
||||||
#};
|
#};
|
||||||
|
|
||||||
home.packages = (with pkgs; [
|
|
||||||
git
|
|
||||||
chromium
|
|
||||||
wl-clipboard
|
|
||||||
wl-clipboard-x11
|
|
||||||
(callPackage ../derivations/audiorelay.nix { })
|
|
||||||
(callPackage ../derivations/spotify.nix { })
|
|
||||||
#(callPackage ../derivations/nu_plugin_dns.nix { })
|
|
||||||
xorg.xwininfo
|
|
||||||
jq
|
|
||||||
dropbox
|
|
||||||
]) ++ (with unstable; [
|
|
||||||
xfce.thunar
|
|
||||||
rustdesk-flutter
|
|
||||||
autossh
|
|
||||||
scrcpy
|
|
||||||
nixfmt
|
|
||||||
btop
|
|
||||||
htop
|
|
||||||
foot
|
|
||||||
alacritty
|
|
||||||
dig
|
|
||||||
nwg-displays
|
|
||||||
nwg-drawer
|
|
||||||
imagemagick
|
|
||||||
fastfetch
|
|
||||||
hyfetch
|
|
||||||
pavucontrol
|
|
||||||
wget
|
|
||||||
wlogout
|
|
||||||
nom
|
|
||||||
vesktop
|
|
||||||
firefox
|
|
||||||
]) ++ (with stable; [
|
|
||||||
localsend
|
|
||||||
trayscale
|
|
||||||
]) ++ ([
|
|
||||||
# inputs.firefox.packages.${pkgs.system}.firefox-bin
|
|
||||||
]);
|
|
||||||
|
|
||||||
|
|
||||||
programs.obs-studio = {
|
programs.obs-studio = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,6 @@ let
|
||||||
"Iosevka"
|
"Iosevka"
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
#cursor-theme = "Qogir";
|
|
||||||
#cursor-package = pkgs.qogir-icon-theme;
|
|
||||||
in {
|
in {
|
||||||
home = {
|
home = {
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
|
|
@ -55,6 +52,14 @@ in {
|
||||||
|
|
||||||
fonts.fontconfig.enable = true;
|
fonts.fontconfig.enable = true;
|
||||||
|
|
||||||
|
pointerCursor = {
|
||||||
|
gtk.enable = true;
|
||||||
|
x11.enable = true;
|
||||||
|
package = pkgs.bibata-cursors;
|
||||||
|
name = "Bibata-Modern-Classic";
|
||||||
|
size = 16;
|
||||||
|
};
|
||||||
|
|
||||||
gtk = {
|
gtk = {
|
||||||
enable = true;
|
enable = true;
|
||||||
#font.name = "Iosevka Malie";
|
#font.name = "Iosevka Malie";
|
||||||
|
|
|
||||||
120
hosts/dlaptop/apps.nix
Normal file
120
hosts/dlaptop/apps.nix
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
{ pkgs, lib, inputs, stable, ... }:
|
||||||
|
let
|
||||||
|
lock-false = {
|
||||||
|
Value = false;
|
||||||
|
Status = "locked";
|
||||||
|
};
|
||||||
|
lock-true = {
|
||||||
|
Value = true;
|
||||||
|
Status = "locked";
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
|
||||||
|
users.users.delta.packages = (with pkgs; [
|
||||||
|
git
|
||||||
|
chromium
|
||||||
|
wl-clipboard
|
||||||
|
wl-clipboard-x11
|
||||||
|
(callPackage ../../derivations/audiorelay.nix { })
|
||||||
|
(callPackage ../../derivations/spotify.nix { })
|
||||||
|
#(callPackage ../derivations/nu_plugin_dns.nix { })
|
||||||
|
xorg.xwininfo
|
||||||
|
jq
|
||||||
|
dropbox
|
||||||
|
spotdl
|
||||||
|
xfce.thunar
|
||||||
|
rustdesk-flutter
|
||||||
|
autossh
|
||||||
|
scrcpy
|
||||||
|
nixfmt
|
||||||
|
btop
|
||||||
|
htop
|
||||||
|
foot
|
||||||
|
alacritty
|
||||||
|
dig
|
||||||
|
nwg-displays
|
||||||
|
nwg-drawer
|
||||||
|
imagemagick
|
||||||
|
fastfetch
|
||||||
|
hyfetch
|
||||||
|
pavucontrol
|
||||||
|
wget
|
||||||
|
wlogout
|
||||||
|
nom
|
||||||
|
vesktop
|
||||||
|
localsend
|
||||||
|
trayscale
|
||||||
|
# inputs.firefox.packages.${pkgs.system}.firefox-bin
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
programs.firefox = {
|
||||||
|
enable = true;
|
||||||
|
policies = {
|
||||||
|
DisableTelemetry = true;
|
||||||
|
DisableFirefoxStudies = true;
|
||||||
|
DisablePocket = true;
|
||||||
|
DisableFirefoxAccounts = true;
|
||||||
|
DisableAccounts = true;
|
||||||
|
DisableFirefoxScreenshots = true;
|
||||||
|
DisplayBookmarksToolbar = "never";
|
||||||
|
DNSOverHTTPS = {
|
||||||
|
Enabled = false;
|
||||||
|
ProviderURL = "https://mozilla.cloudflare-dns.com/dns-query";
|
||||||
|
Locked = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
Preferences = {
|
||||||
|
"ui.key.menuAccessKeyFocuses" = lock-false;
|
||||||
|
"signon.generation.enabled" = lock-false;
|
||||||
|
"browser.compactmode.show" = lock-true;
|
||||||
|
"browser.uidensity" = {
|
||||||
|
Value = 1;
|
||||||
|
Status = "Locked";
|
||||||
|
};
|
||||||
|
"mousewheel.with_alt.action" = {
|
||||||
|
Value = "-1";
|
||||||
|
Status = "Locked";
|
||||||
|
};
|
||||||
|
"browser.tabs.firefox-view" = lock-false;
|
||||||
|
};
|
||||||
|
|
||||||
|
# https://discourse.nixos.org/t/declare-firefox-extensions-and-settings/36265/17
|
||||||
|
# about:debugging#/runtime/this-firefox
|
||||||
|
ExtensionSettings = with builtins;
|
||||||
|
let
|
||||||
|
extension = shortId: uuid: {
|
||||||
|
name = uuid;
|
||||||
|
value = {
|
||||||
|
install_url =
|
||||||
|
"https://addons.mozilla.org/en-US/firefox/downloads/latest/${shortId}/latest.xpi";
|
||||||
|
installation_mode = "normal_installed";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in listToAttrs [
|
||||||
|
(extension "ublock-origin" "uBlock0@raymondhill.net")
|
||||||
|
(extension "container-proxy" "contaner-proxy@bekh-ivanov.me")
|
||||||
|
(extension "clearurls" "{74145f27-f039-47ce-a470-a662b129930a}")
|
||||||
|
(extension "darkreader" "addon@darkreader.org")
|
||||||
|
(extension "firefox-color" "FirefoxColor@mozilla.com")
|
||||||
|
(extension "multi-account-containers" "@testpilot-containers")
|
||||||
|
(extension "jkcs" "{6d9f4f04-2499-4fed-ae4a-02c5658c5d00}")
|
||||||
|
(extension "keepassxc-browser" "keepassxc-browser@keepassxc.org")
|
||||||
|
(extension "new-window-without-toolbar"
|
||||||
|
"new-window-without-toolbar@tkrkt.com")
|
||||||
|
(extension "open-in-spotify-desktop"
|
||||||
|
"{04a727ec-f366-4f19-84bc-14b41af73e4d}")
|
||||||
|
(extension "search_by_image" "{2e5ff8c8-32fe-46d0-9fc8-6b8986621f3c}")
|
||||||
|
(extension "single-file" "{531906d3-e22f-4a6c-a102-8057b88a1a63}")
|
||||||
|
(extension "soundfixer" "soundfixer@unrelenting.technology")
|
||||||
|
(extension "sponsorblock" "sponsorBlocker@ajay.app")
|
||||||
|
(extension "tampermonkey" "firefox@tampermonkey.net")
|
||||||
|
#(extension "torrent-control" "{e6e36c9a-8323-446c-b720-a176017e38ff}")
|
||||||
|
(extension "unpaywall" "{f209234a-76f0-4735-9920-eb62507a54cd}")
|
||||||
|
(extension "ctrl-number-to-switch-tabs"
|
||||||
|
"{84601290-bec9-494a-b11c-1baa897a9683}")
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
./sops.nix
|
./sops.nix
|
||||||
|
./socks.nix
|
||||||
|
./apps.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -140,7 +142,7 @@
|
||||||
source = "${pkgs.firejail.out}/bin/firejail";
|
source = "${pkgs.firejail.out}/bin/firejail";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
pam.loginLimits = [{
|
pam.loginLimits = [{ #needed for swaylock
|
||||||
domain = "@users";
|
domain = "@users";
|
||||||
item = "rtprio";
|
item = "rtprio";
|
||||||
type = "-";
|
type = "-";
|
||||||
|
|
@ -224,7 +226,30 @@
|
||||||
services.blueman.enable = true;
|
services.blueman.enable = true;
|
||||||
services.tumbler.enable = true;
|
services.tumbler.enable = true;
|
||||||
services.gvfs.enable = true;
|
services.gvfs.enable = true;
|
||||||
services.udev.packages = [ pkgs.gnome.gnome-settings-daemon pkgs.android-udev-rules ];
|
services.udev.packages = [
|
||||||
|
pkgs.gnome.gnome-settings-daemon
|
||||||
|
pkgs.android-udev-rules
|
||||||
|
pkgs.yubikey-personalization
|
||||||
|
];
|
||||||
|
#services.udev.extraRules = ''
|
||||||
|
# #yubikey autostart
|
||||||
|
# ENV{ID_VENDOR}=="Yubico", ENV{ID_VENDOR_ID}=="1050", ENV{ID_MODEL_ID}=="0010|0111|0112|0113|0114|0115|0116|0401|0402|0403|0404|0405|0406|0407|0410", SYMLINK+="yubikey", TAG+="systemd"
|
||||||
|
#'';
|
||||||
|
#systemd.user.services.yubioath = {
|
||||||
|
# enable = true;
|
||||||
|
# description = "Autostart Yubico Authenticator";
|
||||||
|
# after = [ "dev-yubikey.device" ];
|
||||||
|
# unitConfig = {
|
||||||
|
# StopPropagatedFrom="dev-yubikey.device"; #comment to not close app after yubi remove
|
||||||
|
# };
|
||||||
|
# serviceConfig = {
|
||||||
|
# Type = "oneshot";
|
||||||
|
# };
|
||||||
|
#
|
||||||
|
# script = "${pkgs.yubioath-flutter}/bin/yubioath-flutter";
|
||||||
|
#};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
programs.thunar.enable = true;
|
programs.thunar.enable = true;
|
||||||
programs.firejail.enable = true;
|
programs.firejail.enable = true;
|
||||||
|
|
@ -290,8 +315,6 @@
|
||||||
gnomeExtensions.clipboard-indicator
|
gnomeExtensions.clipboard-indicator
|
||||||
gnomeExtensions.tiling-assistant
|
gnomeExtensions.tiling-assistant
|
||||||
#gnomeExtensions.wintile-windows-10-window-tiling-for-gnome
|
#gnomeExtensions.wintile-windows-10-window-tiling-for-gnome
|
||||||
gnomeExtensions.advanced-alttab-window-switcher
|
|
||||||
gnomeExtensions.syncthing-indicator
|
|
||||||
gnome.gnome-tweaks
|
gnome.gnome-tweaks
|
||||||
|
|
||||||
mojave-gtk-theme
|
mojave-gtk-theme
|
||||||
|
|
@ -312,30 +335,50 @@
|
||||||
inputs.telegram-desktop-patched.packages.${pkgs.system}.default
|
inputs.telegram-desktop-patched.packages.${pkgs.system}.default
|
||||||
# inputs.ragenix.packages.x86_64-linux.default
|
# inputs.ragenix.packages.x86_64-linux.default
|
||||||
sops
|
sops
|
||||||
];
|
yubikey-manager-qt
|
||||||
|
yubico-piv-tool
|
||||||
|
yubioath-flutter
|
||||||
|
yubikey-personalization
|
||||||
|
yubikey-personalization-gui
|
||||||
|
(pkgs.writeScriptBin "warp-cli" "${pkgs.cloudflare-warp}/bin/warp-cli $@")
|
||||||
|
age-plugin-yubikey
|
||||||
|
];
|
||||||
|
|
||||||
users.users.socks = {
|
services.pcscd.enable = true;
|
||||||
group = "socks";
|
|
||||||
isSystemUser = true;
|
|
||||||
};
|
|
||||||
users.groups.socks = { };
|
|
||||||
|
|
||||||
systemd.services.singbox-aus = {
|
#users.users.socks = {
|
||||||
|
# group = "socks";
|
||||||
|
# isSystemUser = true;
|
||||||
|
#};
|
||||||
|
#users.groups.socks = { };
|
||||||
|
|
||||||
|
#systemd.services.singbox-aus = {
|
||||||
|
# enable = true;
|
||||||
|
# description = "avoid censorship";
|
||||||
|
# wantedBy = [ "multi-user.target" ];
|
||||||
|
# serviceConfig = {
|
||||||
|
# Restart = "on-failure";
|
||||||
|
# RestartSec = "15";
|
||||||
|
# User = "socks";
|
||||||
|
# Group = "socks";
|
||||||
|
# };
|
||||||
|
# script = "sing-box run -c /run/secrets/singbox-aus";
|
||||||
|
# path = with unstable; [
|
||||||
|
# shadowsocks-libev
|
||||||
|
# shadowsocks-v2ray-plugin
|
||||||
|
# sing-box
|
||||||
|
# ];
|
||||||
|
#};
|
||||||
|
|
||||||
|
systemd.services.cloudflare-warp = {
|
||||||
enable = true;
|
enable = true;
|
||||||
description = "avoid censorship";
|
description = "cloudflare warp service";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
RestartSec = "15";
|
RestartSec = "15";
|
||||||
User = "socks";
|
|
||||||
Group = "socks";
|
|
||||||
};
|
};
|
||||||
script = "sing-box run -c /run/secrets/singbox-aus";
|
script = "${pkgs.cloudflare-warp}/bin/warp-svc";
|
||||||
path = with unstable; [
|
|
||||||
shadowsocks-libev
|
|
||||||
shadowsocks-v2ray-plugin
|
|
||||||
sing-box
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#config.services.openssh.hostKeys = [ "/home/delta/.ssh/id_ed25519" ];
|
#config.services.openssh.hostKeys = [ "/home/delta/.ssh/id_ed25519" ];
|
||||||
|
|
|
||||||
140
hosts/dlaptop/socks.nix
Normal file
140
hosts/dlaptop/socks.nix
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
{ pkgs, lib, ... }:
|
||||||
|
let
|
||||||
|
socksBuilder = attrs:
|
||||||
|
{
|
||||||
|
inherit (attrs) name;
|
||||||
|
value = {
|
||||||
|
enable = true;
|
||||||
|
after = [ "novpn.service" "network-online.target" ];
|
||||||
|
wants = [ "novpn.service" "network-online.target" ];
|
||||||
|
bindsTo = [ "novpn.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = "15";
|
||||||
|
Type = "simple";
|
||||||
|
NetworkNamespacePath = "/run/netns/novpn";
|
||||||
|
User = "socks";
|
||||||
|
Group = "socks";
|
||||||
|
};
|
||||||
|
|
||||||
|
script = attrs.script;
|
||||||
|
preStart = "while true; do ip addr show dev novpn1 | grep -q 'inet' && break; sleep 1; done";
|
||||||
|
|
||||||
|
path = with pkgs; [shadowsocks-libev shadowsocks-v2ray-plugin sing-box wireproxy iproute2 ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# IP of the proxies is 192.168.150.2
|
||||||
|
|
||||||
|
socksed = [
|
||||||
|
{ name = "singbox-aus"; script = "sing-box run -c /run/secrets/singbox-aus"; } # port 4000
|
||||||
|
#{ name = "socks-warp"; script = "wireproxy -c /etc/wireguard/warp0.conf"; } # port 3333
|
||||||
|
];
|
||||||
|
|
||||||
|
start_novpn = pkgs.writeScriptBin "start_novpn" ''
|
||||||
|
#!${pkgs.bash}/bin/bash
|
||||||
|
configure_rules() {
|
||||||
|
ip rule del fwmark 100 table 150
|
||||||
|
ip rule del from 192.168.150.2 table 150
|
||||||
|
ip rule del to 192.168.150.2 table 150
|
||||||
|
ip route del default via $default_gateway dev $default_interface table 150
|
||||||
|
ip route del 192.168.150.2 via 192.168.150.1 dev novpn0 table 150
|
||||||
|
|
||||||
|
ip rule add fwmark 100 table 150
|
||||||
|
ip rule add from 192.168.150.2 table 150
|
||||||
|
ip rule add to 192.168.150.2 table 150
|
||||||
|
ip route add default via $default_gateway dev $default_interface table 150
|
||||||
|
ip route add 192.168.150.2 via 192.168.150.1 dev novpn0 table 150
|
||||||
|
}
|
||||||
|
|
||||||
|
default_gateway=$(ip route | awk '/default/ {print $3}')
|
||||||
|
default_interface=$(ip route | awk '/default/ {print $5}')
|
||||||
|
|
||||||
|
if [[ -z "$default_interface" ]]; then
|
||||||
|
echo "No default interface"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p /etc/netns/novpn/
|
||||||
|
echo "nameserver 1.1.1.1" > /etc/netns/novpn/resolv.conf
|
||||||
|
echo "nameserver 1.1.0.1" >> /etc/netns/novpn/resolv.conf
|
||||||
|
sysctl -wq net.ipv4.ip_forward=1
|
||||||
|
iptables -t nat -A POSTROUTING -o "$default_interface" -j MASQUERADE
|
||||||
|
|
||||||
|
ip link add novpn0 type veth peer name novpn1
|
||||||
|
ip link set novpn1 netns novpn
|
||||||
|
ip addr add 192.168.150.1/24 dev novpn0
|
||||||
|
ip link set novpn0 up
|
||||||
|
ip netns exec novpn ip link set lo up
|
||||||
|
ip netns exec novpn ip addr add 192.168.150.2/24 dev novpn1
|
||||||
|
ip netns exec novpn ip link set novpn1 up
|
||||||
|
ip netns exec novpn ip route add default via 192.168.150.1
|
||||||
|
|
||||||
|
configure_rules
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
ip monitor route | while read -r event; do
|
||||||
|
case "$event" in
|
||||||
|
'local '*)
|
||||||
|
default_interface_new=$(ip route | awk '/default/ {print $5}')
|
||||||
|
default_gateway_new=$(ip route | awk '/default/ {print $3}')
|
||||||
|
|
||||||
|
if [[ ! -z "$default_interface_new" && ! -z "$default_gateway_new" ]]; then
|
||||||
|
default_interface=$default_interface_new
|
||||||
|
default_gateway=$default_gateway_new
|
||||||
|
fi
|
||||||
|
|
||||||
|
configure_rules
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
|
||||||
|
stop_novpn = pkgs.writeScriptBin "stop_novpn" ''
|
||||||
|
#!${pkgs.bash}/bin/bash
|
||||||
|
rm -rf /etc/netns/novpn/
|
||||||
|
ip rule del fwmark 100 table 150
|
||||||
|
ip rule del from 192.168.150.2 table 150
|
||||||
|
ip rule del to 192.168.150.2 table 150
|
||||||
|
ip link del novpn0
|
||||||
|
ip netns del novpn
|
||||||
|
rm -rf /var/run/netns/novpn/
|
||||||
|
exit 0
|
||||||
|
'';
|
||||||
|
|
||||||
|
novpn = {
|
||||||
|
enable = true;
|
||||||
|
description = "novpn namespace";
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = map (s: "${s.name}.service") socksed;
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = "15";
|
||||||
|
ExecStart = "${start_novpn}/bin/start_novpn";
|
||||||
|
ExecStop = "${stop_novpn}/bin/stop_novpn";
|
||||||
|
Type = "simple";
|
||||||
|
};
|
||||||
|
|
||||||
|
preStart = "${stop_novpn}/bin/stop_novpn && ip netns add novpn";
|
||||||
|
path = with pkgs; [ gawk iproute2 iptables sysctl coreutils ];
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
users.users.socks = {
|
||||||
|
group = "socks";
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.socks = {};
|
||||||
|
systemd.services = builtins.listToAttrs (map socksBuilder socksed) // { novpn = novpn; };
|
||||||
|
|
||||||
|
users.users.delta.packages = [ (pkgs.makeDesktopItem {
|
||||||
|
name = "firefox-russia";
|
||||||
|
desktopName = "Firefox Russia";
|
||||||
|
icon = "firefox-developer-edition";
|
||||||
|
exec = ''firejail --blacklist="/var/run/nscd" --ignore="include whitelist-run-common.inc" --netns=novpn firefox -P russia -no-remote'';
|
||||||
|
}) ];
|
||||||
|
}
|
||||||
|
|
@ -76,7 +76,7 @@ in {
|
||||||
shellAliases = {
|
shellAliases = {
|
||||||
rebuild = "nh os switch";
|
rebuild = "nh os switch";
|
||||||
rollback = "sudo nixos-rebuild switch --rollback --flake ~/Documents/dotfiles/";
|
rollback = "sudo nixos-rebuild switch --rollback --flake ~/Documents/dotfiles/";
|
||||||
haste = "HASTE_SERVER='https://haste.delch.workers.dev' ${pkgs.haste-client}/bin/haste";
|
haste = "HASTE_SERVER='https://haste.schizoposting.online' ${pkgs.haste-client}/bin/haste";
|
||||||
};
|
};
|
||||||
promptInit = ''
|
promptInit = ''
|
||||||
set TERM "xterm-256color"
|
set TERM "xterm-256color"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"data": "ENC[AES256_GCM,data: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,iv:tLImbd3q9isshrqvmcgUIPm6/1mblyqheQIThc4UmIE=,tag:0keREDJSFAeqGMJpgawA4Q==,type:str]",
|
"data": "ENC[AES256_GCM,data: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,iv://YWpvst+vprLKRa38f+YnlvXxK6G7MRad2ZWlzP1Wc=,tag:IT02mdio1C3boQ9UxyZnHQ==,type:str]",
|
||||||
"sops": {
|
"sops": {
|
||||||
"kms": null,
|
"kms": null,
|
||||||
"gcp_kms": null,
|
"gcp_kms": null,
|
||||||
|
|
@ -11,8 +11,8 @@
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2ME81STBnMHh6eTlJSkpY\nMDdhUUtWaU9UT0NxRGFXNkZDbmNrbkFXekJvCnluSUNMcTcwZ29QcG85S2cxRGZ2\nd3BwcFZ2blBnZiszZ0VyaTBxc1JyMG8KLS0tIEVTWjQ4YXd5S1dzMWJ5R0grVldw\nci9QOFd0b2FuQWV5UUd4OXVpYU40WUkKk4clpuxVZnmm7nmOwVfJ+mrB/lpcM1n8\neHa83IKAhDnGGUZLSO18Wd5s5Hb+HFbU45tEn9AWj603kn9vZMC09g==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2ME81STBnMHh6eTlJSkpY\nMDdhUUtWaU9UT0NxRGFXNkZDbmNrbkFXekJvCnluSUNMcTcwZ29QcG85S2cxRGZ2\nd3BwcFZ2blBnZiszZ0VyaTBxc1JyMG8KLS0tIEVTWjQ4YXd5S1dzMWJ5R0grVldw\nci9QOFd0b2FuQWV5UUd4OXVpYU40WUkKk4clpuxVZnmm7nmOwVfJ+mrB/lpcM1n8\neHa83IKAhDnGGUZLSO18Wd5s5Hb+HFbU45tEn9AWj603kn9vZMC09g==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"lastmodified": "2024-03-15T12:16:27Z",
|
"lastmodified": "2024-03-19T01:06:08Z",
|
||||||
"mac": "ENC[AES256_GCM,data:kshyovsY1yI7o+9EPi/H+NoIzU47j0DVZasg9Mlk3KWQbvT0Q56w7E/mX72/aidSJCColqr9td8zFh8XFv10AG/0seoeayYpxupzTdrm1TFXTUW2uECM7s/vy7IxGQq76rPh2o5LZNz+w30V0EI+yH41nQYoRfo6X1sDhgffBRY=,iv:b/Kcda/YdqotJm8BcvzUWR2CU+wlJ5+YQmAJ5uDRX3Y=,tag:h+181XmbahsepjbJJdJqkA==,type:str]",
|
"mac": "ENC[AES256_GCM,data:cv+YNXn7ZxQj6GgDeDyV9d9rYYa49KQ7PZL/ba3iMt22FQKHRyQiAu9piymZV7apxvQ8XCFNtknP8GTx0pj+dzzNupVpzAIwhcFze2l7lw/QH/LCcKOAQzYUMhP+LkEXBDwkt/yVu4tk7Gr61hBT7pimjOw/9OqjKfC/TVMAqkI=,iv:gl5PIb4NDsuYkxd6O1oKbhnSK4h7aUXnTEuZyiE9Bq8=,tag:xPgjA28o/kv07GmAcu/+4Q==,type:str]",
|
||||||
"pgp": null,
|
"pgp": null,
|
||||||
"unencrypted_suffix": "_unencrypted",
|
"unencrypted_suffix": "_unencrypted",
|
||||||
"version": "3.8.1"
|
"version": "3.8.1"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue