diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 50e3078d977..f94703a881b 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -662,6 +662,8 @@
./services/networking/skydns.nix
./services/networking/shadowsocks.nix
./services/networking/shairport-sync.nix
+ ./services/networking/shorewall.nix
+ ./services/networking/shorewall6.nix
./services/networking/shout.nix
./services/networking/sniproxy.nix
./services/networking/smokeping.nix
diff --git a/nixos/modules/services/networking/shorewall.nix b/nixos/modules/services/networking/shorewall.nix
new file mode 100644
index 00000000000..0f94d414fcf
--- /dev/null
+++ b/nixos/modules/services/networking/shorewall.nix
@@ -0,0 +1,75 @@
+{ config, lib, pkgs, ... }:
+let
+ types = lib.types;
+ cfg = config.services.shorewall;
+in {
+ options = {
+ services.shorewall = {
+ enable = lib.mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable Shorewall IPv4 Firewall.
+
+
+ Enabling this service WILL disable the existing NixOS
+ firewall! Default firewall rules provided by packages are not
+ considered at the moment.
+
+
+ '';
+ };
+ package = lib.mkOption {
+ type = types.package;
+ default = pkgs.shorewall;
+ defaultText = "pkgs.shorewall";
+ description = "The shorewall package to use.";
+ };
+ configs = lib.mkOption {
+ type = types.attrsOf types.str;
+ default = {};
+ description = ''
+ This option defines the Shorewall configs.
+ The attribute name defines the name of the config,
+ and the attribute value defines the content of the config.
+ '';
+ apply = lib.mapAttrs (name: text: pkgs.writeText "${name}" text);
+ };
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ systemd.services.firewall.enable = false;
+ systemd.services.shorewall = {
+ description = "Shorewall IPv4 Firewall";
+ after = [ "ipset.target" ];
+ before = [ "network-pre.target" ];
+ wants = [ "network-pre.target" ];
+ wantedBy = [ "multi-user.target" ];
+ reloadIfChanged = true;
+ restartTriggers = lib.attrValues cfg.configs;
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = "yes";
+ ExecStart = "${cfg.package}/bin/shorewall start";
+ ExecReload = "${cfg.package}/bin/shorewall reload";
+ ExecStop = "${cfg.package}/bin/shorewall stop";
+ };
+ preStart = ''
+ install -D -d -m 750 /var/lib/shorewall
+ install -D -d -m 755 /var/lock/subsys
+ touch /var/log/shorewall.log
+ chown 750 /var/log/shorewall.log
+ '';
+ };
+ environment = {
+ etc = lib.mapAttrsToList
+ (name: file:
+ { source = file;
+ target = "shorewall/${name}";
+ })
+ cfg.configs;
+ systemPackages = [ cfg.package ];
+ };
+ };
+}
diff --git a/nixos/modules/services/networking/shorewall6.nix b/nixos/modules/services/networking/shorewall6.nix
new file mode 100644
index 00000000000..9c22a037c0b
--- /dev/null
+++ b/nixos/modules/services/networking/shorewall6.nix
@@ -0,0 +1,75 @@
+{ config, lib, pkgs, ... }:
+let
+ types = lib.types;
+ cfg = config.services.shorewall6;
+in {
+ options = {
+ services.shorewall6 = {
+ enable = lib.mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable Shorewall IPv6 Firewall.
+
+
+ Enabling this service WILL disable the existing NixOS
+ firewall! Default firewall rules provided by packages are not
+ considered at the moment.
+
+
+ '';
+ };
+ package = lib.mkOption {
+ type = types.package;
+ default = pkgs.shorewall;
+ defaultText = "pkgs.shorewall";
+ description = "The shorewall package to use.";
+ };
+ configs = lib.mkOption {
+ type = types.attrsOf types.str;
+ default = {};
+ description = ''
+ This option defines the Shorewall configs.
+ The attribute name defines the name of the config,
+ and the attribute value defines the content of the config.
+ '';
+ apply = lib.mapAttrs (name: text: pkgs.writeText "${name}" text);
+ };
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ systemd.services.firewall.enable = false;
+ systemd.services.shorewall6 = {
+ description = "Shorewall IPv6 Firewall";
+ after = [ "ipset.target" ];
+ before = [ "network-pre.target" ];
+ wants = [ "network-pre.target" ];
+ wantedBy = [ "multi-user.target" ];
+ reloadIfChanged = true;
+ restartTriggers = lib.attrValues cfg.configs;
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = "yes";
+ ExecStart = "${cfg.package}/bin/shorewall6 start";
+ ExecReload = "${cfg.package}/bin/shorewall6 reload";
+ ExecStop = "${cfg.package}/bin/shorewall6 stop";
+ };
+ preStart = ''
+ install -D -d -m 750 /var/lib/shorewall6
+ install -D -d -m 755 /var/lock/subsys
+ touch /var/log/shorewall6.log
+ chown 750 /var/log/shorewall6.log
+ '';
+ };
+ environment = {
+ etc = lib.mapAttrsToList
+ (name: file:
+ { source = file;
+ target = "shorewall6/${name}";
+ })
+ cfg.configs;
+ systemPackages = [ cfg.package ];
+ };
+ };
+}
diff --git a/pkgs/tools/networking/shorewall/default.nix b/pkgs/tools/networking/shorewall/default.nix
new file mode 100644
index 00000000000..8e62aa735a4
--- /dev/null
+++ b/pkgs/tools/networking/shorewall/default.nix
@@ -0,0 +1,130 @@
+{ coreutils
+, ebtables
+, fetchurl
+, gnugrep
+, gnused
+, iproute
+, ipset
+, iptables
+, perl
+, perlPackages
+, stdenv
+, tree
+, utillinux
+}:
+let
+ PATH = stdenv.lib.concatStringsSep ":"
+ [ "${coreutils}/bin"
+ "${iproute}/bin"
+ "${iptables}/bin"
+ "${ipset}/bin"
+ "${ebtables}/bin"
+ "${utillinux}/bin"
+ "${gnugrep}/bin"
+ "${gnused}/bin"
+ ];
+in
+stdenv.mkDerivation rec {
+ pname = "shorewall";
+ version = "5.2.3.3";
+
+ srcs = [
+ (fetchurl {
+ url = "http://www.shorewall.net/pub/shorewall/5.2/shorewall-5.2.3/shorewall-core-${version}.tar.bz2";
+ sha256 = "1gg2yfxzm3y9qqjrrg5nq2ggi1c6yfxx0s7fvwjw70b185mwa5p5";
+ })
+ (fetchurl {
+ url = "http://www.shorewall.net/pub/shorewall/5.2/shorewall-5.2.3/shorewall-${version}.tar.bz2";
+ sha256 = "1ka70pa3s0cnvc83rlm57r05cdv9idnxnq0vmxi6nr7razak5f3b";
+ })
+ (fetchurl {
+ url = "http://www.shorewall.net/pub/shorewall/5.2/shorewall-5.2.3/shorewall6-${version}.tar.bz2";
+ sha256 = "0mhs4m6agwk082h1n69gnyfsjpycdd8215r4r9rzb3czs5xi087n";
+ })
+ ];
+ sourceRoot = ".";
+
+ buildInputs = [
+ coreutils
+ iproute
+ ipset
+ iptables
+ ebtables
+ utillinux
+ gnugrep
+ gnused
+ perl
+ ] ++ (with perlPackages; [
+ DigestSHA1
+ ]);
+ prePatch = ''
+ # Patch configure and install.sh files
+ patchShebangs .
+
+ # Remove hardcoded PATH
+ sed -i shorewall-core-${version}/lib.cli \
+ -e '/^ *PATH=.*/d'
+ '';
+ configurePhase = ''
+ shorewall-core-${version}/configure \
+ HOST=linux \
+ PREFIX=$out \
+ CONFDIR=\$PREFIX/etc-example \
+ SBINDIR=\$PREFIX/sbin \
+ SYSCONFDIR= \
+ SHAREDIR=\$PREFIX/share \
+ LIBEXECDIR=\$SHAREDIR \
+ PERLLIBDIR=\$SHAREDIR/shorewall \
+ MANDIR=$out/man \
+ VARLIB=/var/lib \
+ INITSOURCE= \
+ INITDIR= \
+ INITFILE= \
+ DEFAULT_PAGER=
+ '';
+ installPhase = ''
+ export DESTDIR=/
+ shorewall-core-${version}/install.sh
+
+ ln -s ../shorewall-core-${version}/shorewallrc shorewall-${version}/
+ shorewall-${version}/install.sh
+
+ ln -s ../shorewall-core-${version}/shorewallrc shorewall6-${version}/
+ shorewall6-${version}/install.sh
+
+ # Patch the example shorewall{,6}.conf in case it is included
+ # in services.shorewall{,6}.configs
+ sed -i $out/etc-example/shorewall/shorewall.conf \
+ $out/etc-example/shorewall6/shorewall6.conf \
+ -e 's|^LOGFILE=.*|LOGFILE=/var/log/shorewall.log|' \
+ -e 's|^PATH=.*|PATH=${PATH}|' \
+ -e 's|^PERL=.*|PERL=${perl}/bin/perl|' \
+ -e 's|^SHOREWALL_SHELL=.*|SHOREWALL_SHELL=${stdenv.shell}|'
+ sed -i $out/etc-example/shorewall6/shorewall6.conf \
+ -e 's|^CONFIG_PATH=.*|CONFIG_PATH=:''${CONFDIR}/shorewall6:''${SHAREDIR}/shorewall6:''${SHAREDIR}/shorewall|'
+ # FIXME: the default GEOIPDIR=/usr/share/xt_geoip/LE may require attention.
+
+ # Redirect CONFDIR to /etc where services.shorewall{,6}.configs
+ # will generate the config files.
+ sed -i $out/share/shorewall/shorewallrc \
+ -e 's~^CONFDIR=.*~CONFDIR=/etc~'
+ '';
+
+ meta = {
+ homepage = http://www.shorewall.net/;
+ description = "An IP gateway/firewall configuration tool for GNU/Linux";
+ longDescription = ''
+ Shorewall is a high-level tool for configuring Netfilter. You describe your
+ firewall/gateway requirements using entries in a set of configuration
+ files. Shorewall reads those configuration files and with the help of the
+ iptables, iptables-restore, ip and tc utilities, Shorewall configures
+ Netfilter and the Linux networking subsystem to match your requirements.
+ Shorewall can be used on a dedicated firewall system, a multi-function
+ gateway/router/server or on a standalone GNU/Linux system. Shorewall does
+ not use Netfilter's ipchains compatibility mode and can thus take
+ advantage of Netfilter's connection state tracking capabilities.
+ '';
+ license = stdenv.lib.licenses.gpl2Plus;
+ platforms = stdenv.lib.platforms.linux;
+ };
+}
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index fecf53c3f4d..b4bb3f36471 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -5831,6 +5831,8 @@ in
shocco = callPackage ../tools/text/shocco { };
+ shorewall = callPackage ../tools/networking/shorewall { };
+
shotwell = callPackage ../applications/graphics/shotwell { };
shout = nodePackages.shout;