Compare commits
17 Commits
08f9b64e3f
...
ba6e4f3a4c
Author | SHA1 | Date |
---|---|---|
eum3l | ba6e4f3a4c | |
Toby | 3ec5456e86 | |
Toby | b51ea5fa07 | |
Toby | 2ac8783eb6 | |
Toby | 5014523ae0 | |
Toby | dabcc9566c | |
Toby | c453020349 | |
Toby | 0daaa32fc6 | |
Toby | 5e15fd6dd9 | |
Toby | 76c0f47832 | |
Toby | 70fee14103 | |
eddc005 | abd7725fed | |
eddc005 | f01b79e625 | |
eddc005 | 94387450cf | |
eum3l | 40a1fb707d | |
eum3l | 9edaba0f8f | |
eum3l | aca830d189 |
|
@ -0,0 +1,130 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1705309234,
|
||||
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_2": {
|
||||
"inputs": {
|
||||
"systems": "systems_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1694529238,
|
||||
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gomod2nix": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_2",
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1705314449,
|
||||
"narHash": "sha256-yfQQ67dLejP0FLK76LKHbkzcQqNIrux6MFe32MMFGNQ=",
|
||||
"owner": "nix-community",
|
||||
"repo": "gomod2nix",
|
||||
"rev": "30e3c3a9ec4ac8453282ca7f67fca9e1da12c3e6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "gomod2nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1658285632,
|
||||
"narHash": "sha256-zRS5S/hoeDGUbO+L95wXG9vJNwsSYcl93XiD0HQBXLk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "5342fc6fb59d0595d26883c3cadff16ce58e44f3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "master",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1701282334,
|
||||
"narHash": "sha256-MxCVrXY6v4QmfTwIysjjaX0XUhqBbxTWWB4HXtDYsdk=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "057f9aecfb71c4437d2b27d3323df7f93c010b7e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "23.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"gomod2nix": "gomod2nix",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_2": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
description = "OpenGFW is a flexible, easy-to-use, open source implementation of GFW on Linux.";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs?ref=23.11";
|
||||
gomod2nix.url = "github:nix-community/gomod2nix";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
gomod2nix,
|
||||
flake-utils,
|
||||
}:
|
||||
flake-utils.lib.eachDefaultSystem (
|
||||
system: let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
config.allowUnsupportedSystem = true;
|
||||
overlays = [
|
||||
gomod2nix.overlays.default
|
||||
];
|
||||
};
|
||||
in {
|
||||
packages = rec {
|
||||
opengfw = pkgs.callPackage ./nix/package.nix {};
|
||||
default = opengfw;
|
||||
};
|
||||
|
||||
devShells.default = pkgs.mkShell {
|
||||
OPENGFW_LOG_LEVEL = "debug";
|
||||
buildInputs = let
|
||||
goEnv = pkgs.mkGoEnv {pwd = ./.;};
|
||||
in [
|
||||
goEnv
|
||||
pkgs.gomod2nix
|
||||
];
|
||||
};
|
||||
}
|
||||
)
|
||||
// {
|
||||
nixosModules.opengfw = import ./nix/module.nix self.packages;
|
||||
|
||||
hydraJobs = {
|
||||
inherit (self) packages;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
schema = 3
|
||||
|
||||
[mod]
|
||||
[mod."github.com/bwmarrin/snowflake"]
|
||||
version = "v0.3.0"
|
||||
hash = "sha256-mOU/CgyC9W8XwuinYTPOH69wJY/f+nFVZjZ8lAr9fGM="
|
||||
[mod."github.com/coreos/go-iptables"]
|
||||
version = "v0.7.0"
|
||||
hash = "sha256-6zG74a2qK8NnmKGL3Cv1IGDP/MSY/PYZpEcJT8bl7JU="
|
||||
[mod."github.com/davecgh/go-spew"]
|
||||
version = "v1.1.2-0.20180830191138-d8f796af33cc"
|
||||
hash = "sha256-fV9oI51xjHdOmEx6+dlq7Ku2Ag+m/bmbzPo6A4Y74qc="
|
||||
[mod."github.com/expr-lang/expr"]
|
||||
version = "v1.15.7"
|
||||
hash = "sha256-mQ8LOe+9hu72XTlQdymBrUsMBA7JB7S1G7Nob9hZNfo="
|
||||
[mod."github.com/florianl/go-nfqueue"]
|
||||
version = "v1.3.2-0.20231218173729-f2bdeb033acf"
|
||||
hash = "sha256-KErxiIfDWHXrvJp0yweQ59M6lwmsY2McyKFaNVD6ifg="
|
||||
[mod."github.com/fsnotify/fsnotify"]
|
||||
version = "v1.7.0"
|
||||
hash = "sha256-MdT2rQyQHspPJcx6n9ozkLbsktIOJutOqDuKpNAtoZY="
|
||||
[mod."github.com/google/go-cmp"]
|
||||
version = "v0.5.9"
|
||||
hash = "sha256-lQc4O00R3QSMGs9LP8Sy7A9kj0cqV5rrUdpnGeipIyg="
|
||||
[mod."github.com/google/gopacket"]
|
||||
version = "v1.1.19"
|
||||
hash = "sha256-EueA6b+c7SWJjII3HiFnMMKj3mIbAdzboJo6HBZnkkc="
|
||||
[mod."github.com/hashicorp/golang-lru/v2"]
|
||||
version = "v2.0.7"
|
||||
hash = "sha256-t1bcXLgrQNOYUVyYEZ0knxcXpsTk4IuJZDjKvyJX75g="
|
||||
[mod."github.com/hashicorp/hcl"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-xsRCmYyBfglMxeWUvTZqkaRLSW+V2FvNodEDjTGg1WA="
|
||||
[mod."github.com/inconshreveable/mousetrap"]
|
||||
version = "v1.1.0"
|
||||
hash = "sha256-XWlYH0c8IcxAwQTnIi6WYqq44nOKUylSWxWO/vi+8pE="
|
||||
[mod."github.com/josharian/native"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-ub4WrKNlMAvgn+OPuJYeJJYLyjqeTGDHA97RTzUC6+Y="
|
||||
[mod."github.com/magiconair/properties"]
|
||||
version = "v1.8.7"
|
||||
hash = "sha256-XQ2bnc2s7/IH3WxEO4GishZurMyKwEclZy1DXg+2xXc="
|
||||
[mod."github.com/mdlayher/netlink"]
|
||||
version = "v1.6.0"
|
||||
hash = "sha256-hFm39JacQH6ed6l/Xn10eP8pFVO0BK8a9phdgtj89f8="
|
||||
[mod."github.com/mdlayher/socket"]
|
||||
version = "v0.1.1"
|
||||
hash = "sha256-g3GB7weGxxw8eJmD6VDY6os+zRJEZrmOLVscHGbDVXs="
|
||||
[mod."github.com/mitchellh/mapstructure"]
|
||||
version = "v1.5.0"
|
||||
hash = "sha256-ztVhGQXs67MF8UadVvG72G3ly0ypQW0IRDdOOkjYwoE="
|
||||
[mod."github.com/pelletier/go-toml/v2"]
|
||||
version = "v2.1.0"
|
||||
hash = "sha256-0u6oV8YMM26y2bw1oe3gLmEJc/whpNaFtEe4yOkN24c="
|
||||
[mod."github.com/pmezard/go-difflib"]
|
||||
version = "v1.0.1-0.20181226105442-5d4384ee4fb2"
|
||||
hash = "sha256-XA4Oj1gdmdV/F/+8kMI+DBxKPthZ768hbKsO3d9Gx90="
|
||||
[mod."github.com/sagikazarmark/locafero"]
|
||||
version = "v0.4.0"
|
||||
hash = "sha256-7I1Oatc7GAaHgAqBFO6Tv4IbzFiYeU9bJAfJhXuWaXk="
|
||||
[mod."github.com/sagikazarmark/slog-shim"]
|
||||
version = "v0.1.0"
|
||||
hash = "sha256-F92BQXXmn3mCwu3mBaGh+joTRItQDSDhsjU6SofkYdA="
|
||||
[mod."github.com/sourcegraph/conc"]
|
||||
version = "v0.3.0"
|
||||
hash = "sha256-mIdMs9MLAOBKf3/0quf1iI3v8uNWydy7ae5MFa+F2Ko="
|
||||
[mod."github.com/spf13/afero"]
|
||||
version = "v1.11.0"
|
||||
hash = "sha256-+rV3cDZr13N8E0rJ7iHmwsKYKH+EhV+IXBut+JbBiIE="
|
||||
[mod."github.com/spf13/cast"]
|
||||
version = "v1.6.0"
|
||||
hash = "sha256-hxioqRZfXE0AE5099wmn3YG0AZF8Wda2EB4c7zHF6zI="
|
||||
[mod."github.com/spf13/cobra"]
|
||||
version = "v1.8.0"
|
||||
hash = "sha256-oAE+fEaRfZPE541IPWE0GMeBBYgH2DMhtZNxzp7DFlY="
|
||||
[mod."github.com/spf13/pflag"]
|
||||
version = "v1.0.5"
|
||||
hash = "sha256-w9LLYzxxP74WHT4ouBspH/iQZXjuAh2WQCHsuvyEjAw="
|
||||
[mod."github.com/spf13/viper"]
|
||||
version = "v1.18.2"
|
||||
hash = "sha256-MXYbK6w1LEaoZ2/L/STF3WU1tbK+7NwGVxUCLKPkwks="
|
||||
[mod."github.com/stretchr/testify"]
|
||||
version = "v1.8.4"
|
||||
hash = "sha256-MoOmRzbz9QgiJ+OOBo5h5/LbilhJfRUryvzHJmXAWjo="
|
||||
[mod."github.com/subosito/gotenv"]
|
||||
version = "v1.6.0"
|
||||
hash = "sha256-LspbjTniiq2xAICSXmgqP7carwlNaLqnCTQfw2pa80A="
|
||||
[mod."go.uber.org/multierr"]
|
||||
version = "v1.11.0"
|
||||
hash = "sha256-Lb6rHHfR62Ozg2j2JZy3MKOMKdsfzd1IYTR57r3Mhp0="
|
||||
[mod."go.uber.org/zap"]
|
||||
version = "v1.26.0"
|
||||
hash = "sha256-EUQnALSDtoJryWp01K/PMbRUvQYG1uDbqGnlJ/7thE4="
|
||||
[mod."golang.org/x/exp"]
|
||||
version = "v0.0.0-20230905200255-921286631fa9"
|
||||
hash = "sha256-CyeVwjp12Wqh4ptqfi3KHCWPzOFhE8fSrP3sMjMXvec="
|
||||
[mod."golang.org/x/net"]
|
||||
version = "v0.19.0"
|
||||
hash = "sha256-3M5rKEvJx4cO/q+06cGjR5sxF5JpnUWY0+fQttrWdT4="
|
||||
[mod."golang.org/x/sync"]
|
||||
version = "v0.5.0"
|
||||
hash = "sha256-EAKeODSsct5HhXPmpWJfulKSCkuUu6kkDttnjyZMNcI="
|
||||
[mod."golang.org/x/sys"]
|
||||
version = "v0.15.0"
|
||||
hash = "sha256-n7TlABF6179RzGq3gctPDKDPRtDfnwPdjNCMm8ps2KY="
|
||||
[mod."golang.org/x/text"]
|
||||
version = "v0.14.0"
|
||||
hash = "sha256-yh3B0tom1RfzQBf1RNmfdNWF1PtiqxV41jW1GVS6JAg="
|
||||
[mod."google.golang.org/protobuf"]
|
||||
version = "v1.31.0"
|
||||
hash = "sha256-UdIk+xRaMfdhVICvKRk1THe3R1VU+lWD8hqoW/y8jT0="
|
||||
[mod."gopkg.in/ini.v1"]
|
||||
version = "v1.67.0"
|
||||
hash = "sha256-V10ahGNGT+NLRdKUyRg1dos5RxLBXBk1xutcnquc/+4="
|
||||
[mod."gopkg.in/yaml.v3"]
|
||||
version = "v3.0.1"
|
||||
hash = "sha256-FqL9TKYJ0XkNwJFnq9j0VvJ5ZUU1RvH/52h/f5bkYAU="
|
|
@ -0,0 +1,147 @@
|
|||
packages: {
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkOption types mkIf;
|
||||
cfg = config.services.opengfw;
|
||||
|
||||
settings =
|
||||
if cfg.settings != {}
|
||||
then (pkgs.formats.yaml {}).generate "OpenGFW-Config.yaml" cfg.settings
|
||||
else cfg.settingsFile;
|
||||
rules =
|
||||
if cfg.rules != []
|
||||
then (pkgs.formats.yaml {}).generate "OpenGFW-Rules.yaml" cfg.rules
|
||||
else cfg.rulesFile;
|
||||
in {
|
||||
options.services.opengfw = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "A flexible, easy-to-use, open source implementation of GFW on Linux.");
|
||||
|
||||
package = lib.mkPackageOption packages.${pkgs.system} "opengfw" {
|
||||
default = "opengfw";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
default = "opengfw";
|
||||
type = types.singleLineStr;
|
||||
};
|
||||
|
||||
dir = mkOption {
|
||||
default = "/var/lib/opengfw";
|
||||
type = types.singleLineStr;
|
||||
};
|
||||
|
||||
rulesFile = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
};
|
||||
|
||||
settingsFile = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
default = {};
|
||||
type = types.attrs;
|
||||
example = {
|
||||
io = {
|
||||
queueSize = 1024;
|
||||
local = true;
|
||||
};
|
||||
|
||||
workers = {
|
||||
count = 4;
|
||||
queueSize = 16;
|
||||
tcpMaxBufferedPagesTotal = 4096;
|
||||
tcpMaxBufferedPagesPerConn = 64;
|
||||
udpMaxStreams = 4096;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
rules = mkOption {
|
||||
default = [];
|
||||
type = types.listOf types.attrs;
|
||||
description = ''
|
||||
OpenGFW supports the actions 'allow', 'block', 'drop' and 'modify'
|
||||
as listed on https://github.com/apernet/OpenGFW?tab=readme-ov-file#supported-actions.
|
||||
It uses Expr Language (https://expr-lang.org/docs/language-definition).
|
||||
Properties of the analyzers are documented here: https://github.com/apernet/OpenGFW/blob/master/docs/Analyzers.md.
|
||||
'';
|
||||
example = [
|
||||
{
|
||||
name = "block v2ex http";
|
||||
action = "block";
|
||||
expr = ''string(http?.req?.headers?.host) endsWith "v2ex.com"'';
|
||||
}
|
||||
{
|
||||
name = "block google socks";
|
||||
action = "block";
|
||||
expr = ''string(socks?.req?.addr) endsWith "google.com" && socks?.req?.port == 80'';
|
||||
}
|
||||
{
|
||||
name = "v2ex dns poisoning";
|
||||
action = "modify";
|
||||
modifier = {
|
||||
name = "dns";
|
||||
args = {
|
||||
a = "0.0.0.0";
|
||||
aaaa = "::";
|
||||
};
|
||||
};
|
||||
expr = ''dns != nil && dns.qr && any(dns.questions, {.name endsWith "v2ex.com"})'';
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
security.wrappers.OpenGFW = {
|
||||
owner = cfg.user;
|
||||
group = cfg.user;
|
||||
capabilities = "cap_net_admin+ep";
|
||||
source = "${cfg.package}/bin/OpenGFW";
|
||||
};
|
||||
|
||||
systemd = {
|
||||
services.opengfw = let
|
||||
cu = "${pkgs.coreutils}/bin";
|
||||
in {
|
||||
description = "OpenGFW";
|
||||
wantedBy = ["multi-user.target"];
|
||||
after = ["network.target"];
|
||||
environment.PATH = lib.mkForce "${cu}:${pkgs.iptables}/bin";
|
||||
preStart = mkIf ((cfg.rules != [] && cfg.settings != {}) || (cfg.rulesFile != null && cfg.settingsFile != null)) ''
|
||||
${cu}/ln -sf ${settings} config.yaml
|
||||
${cu}/ln -sf ${rules} rules.yaml
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
WorkingDirectory = cfg.dir;
|
||||
ExecStart = "${config.security.wrapperDir}/OpenGFW -c config.yaml rules.yaml";
|
||||
ExecReload = "${cu}/kill -HUP $MAINPID";
|
||||
Restart = "always";
|
||||
User = cfg.user;
|
||||
};
|
||||
};
|
||||
|
||||
tmpfiles.rules = [
|
||||
"d '${cfg.dir}' 0660 ${cfg.user} ${cfg.user} - -"
|
||||
];
|
||||
};
|
||||
|
||||
users = {
|
||||
users.${cfg.user} = {
|
||||
description = "opengfw user";
|
||||
isNormalUser = true;
|
||||
group = cfg.user;
|
||||
home = cfg.dir;
|
||||
};
|
||||
|
||||
groups.${cfg.user} = {};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
}:
|
||||
pkgs.buildGoApplication rec {
|
||||
pname = "opengfw";
|
||||
version = "0.1.1";
|
||||
pwd = ../.;
|
||||
src = ../.;
|
||||
|
||||
buildPhase = ''
|
||||
go build
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp OpenGFW $out/bin
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "A flexible, easy-to-use, open source implementation of GFW on Linux.";
|
||||
longDescription = ''
|
||||
OpenGFW is a flexible, easy-to-use, open source implementation of GFW on Linux
|
||||
that's in many ways more powerful than the real thing.
|
||||
It's cyber sovereignty you can have on a home router.
|
||||
'';
|
||||
homepage = "https://github.com/apernet/OpenGFW";
|
||||
license = licenses.mpl20;
|
||||
mainProgram = "OpenGFW";
|
||||
platforms = [ "x86_64-linux" "aarch64-linux" ];
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue