Merge branch 'hardened-stdenv' into staging

This commit is contained in:
obadz 2016-08-23 18:50:10 +01:00
commit 8da8aa7ddb
14 changed files with 289 additions and 8 deletions

View file

@ -9,7 +9,8 @@ with lib;
default = false;
description =
'' When enabled, GNU software is chosen by default whenever a there is
a choice between GNU and non-GNU software.
a choice between GNU and non-GNU software (e.g., GNU lsh
vs. OpenSSH).
'';
};
};
@ -32,6 +33,12 @@ with lib;
boot.loader.grub.enable = !pkgs.stdenv.isArm;
boot.loader.grub.version = 2;
# GNU lsh.
services.openssh.enable = false;
services.lshd.enable = true;
programs.ssh.startAgent = false;
services.xserver.startGnuPGAgent = true;
# TODO: GNU dico.
# TODO: GNU Inetutils' inetd.
# TODO: GNU Pies.

View file

@ -404,6 +404,7 @@
./services/networking/softether.nix
./services/networking/spiped.nix
./services/networking/sslh.nix
./services/networking/ssh/lshd.nix
./services/networking/ssh/sshd.nix
./services/networking/strongswan.nix
./services/networking/supplicant.nix

View file

@ -0,0 +1,176 @@
{ config, lib, pkgs, ... }:
with lib;
let
inherit (pkgs) lsh;
cfg = config.services.lshd;
in
{
###### interface
options = {
services.lshd = {
enable = mkOption {
default = false;
description = ''
Whether to enable the GNU lshd SSH2 daemon, which allows
secure remote login.
'';
};
portNumber = mkOption {
default = 22;
description = ''
The port on which to listen for connections.
'';
};
interfaces = mkOption {
default = [];
description = ''
List of network interfaces where listening for connections.
When providing the empty list, `[]', lshd listens on all
network interfaces.
'';
example = [ "localhost" "1.2.3.4:443" ];
};
hostKey = mkOption {
default = "/etc/lsh/host-key";
description = ''
Path to the server's private key. Note that this key must
have been created, e.g., using "lsh-keygen --server |
lsh-writekey --server", so that you can run lshd.
'';
};
syslog = mkOption {
default = true;
description = ''Whether to enable syslog output.'';
};
passwordAuthentication = mkOption {
default = true;
description = ''Whether to enable password authentication.'';
};
publicKeyAuthentication = mkOption {
default = true;
description = ''Whether to enable public key authentication.'';
};
rootLogin = mkOption {
default = false;
description = ''Whether to enable remote root login.'';
};
loginShell = mkOption {
default = null;
description = ''
If non-null, override the default login shell with the
specified value.
'';
example = "/nix/store/xyz-bash-10.0/bin/bash10";
};
srpKeyExchange = mkOption {
default = false;
description = ''
Whether to enable SRP key exchange and user authentication.
'';
};
tcpForwarding = mkOption {
default = true;
description = ''Whether to enable TCP/IP forwarding.'';
};
x11Forwarding = mkOption {
default = true;
description = ''Whether to enable X11 forwarding.'';
};
subsystems = mkOption {
description = ''
List of subsystem-path pairs, where the head of the pair
denotes the subsystem name, and the tail denotes the path to
an executable implementing it.
'';
};
};
};
###### implementation
config = mkIf cfg.enable {
services.lshd.subsystems = [ ["sftp" "${pkgs.lsh}/sbin/sftp-server"] ];
systemd.services.lshd = {
description = "GNU lshd SSH2 daemon";
after = [ "network-interfaces.target" ];
wantedBy = [ "multi-user.target" ];
environment = {
LD_LIBRARY_PATH = config.system.nssModules.path;
};
preStart = ''
test -d /etc/lsh || mkdir -m 0755 -p /etc/lsh
test -d /var/spool/lsh || mkdir -m 0755 -p /var/spool/lsh
if ! test -f /var/spool/lsh/yarrow-seed-file
then
# XXX: It would be nice to provide feedback to the
# user when this fails, so that they can retry it
# manually.
${lsh}/bin/lsh-make-seed --sloppy \
-o /var/spool/lsh/yarrow-seed-file
fi
if ! test -f "${cfg.hostKey}"
then
${lsh}/bin/lsh-keygen --server | \
${lsh}/bin/lsh-writekey --server -o "${cfg.hostKey}"
fi
'';
script = with cfg; ''
${lsh}/sbin/lshd --daemonic \
--password-helper="${lsh}/sbin/lsh-pam-checkpw" \
-p ${toString portNumber} \
${if interfaces == [] then ""
else (concatStrings (map (i: "--interface=\"${i}\"")
interfaces))} \
-h "${hostKey}" \
${if !syslog then "--no-syslog" else ""} \
${if passwordAuthentication then "--password" else "--no-password" } \
${if publicKeyAuthentication then "--publickey" else "--no-publickey" } \
${if rootLogin then "--root-login" else "--no-root-login" } \
${if loginShell != null then "--login-shell=\"${loginShell}\"" else "" } \
${if srpKeyExchange then "--srp-keyexchange" else "--no-srp-keyexchange" } \
${if !tcpForwarding then "--no-tcpip-forward" else "--tcpip-forward"} \
${if x11Forwarding then "--x11-forward" else "--no-x11-forward" } \
--subsystems=${concatStringsSep ","
(map (pair: (head pair) + "=" +
(head (tail pair)))
subsystems)}
'';
};
security.pam.services.lshd = {};
};
}

View file

@ -4,8 +4,12 @@ hardeningCFlags=()
hardeningLDFlags=()
hardeningDisable=${hardeningDisable:-""}
if [[ "$($LD -z 2>&1)" =~ "unknown option" ]]; then
hardeningDisable+=" bindnow relro"
if [[ -z "@ld_supports_bindnow@" ]]; then
hardeningDisable+=" bindnow"
fi
if [[ -z "@ld_supports_relro@" ]]; then
hardeningDisable+=" relro"
fi
if [[ -n "$NIX_DEBUG" ]]; then echo HARDENING: Value of '$hardeningDisable': $hardeningDisable >&2; fi
@ -46,11 +50,11 @@ if [[ ! $hardeningDisable == "all" ]]; then
;;
relro)
if [[ -n "$NIX_DEBUG" ]]; then echo HARDENING: enabling relro >&2; fi
hardeningLDFlags+=('-z relro')
hardeningLDFlags+=('-z' 'relro')
;;
bindnow)
if [[ -n "$NIX_DEBUG" ]]; then echo HARDENING: enabling bindnow >&2; fi
hardeningLDFlags+=('-z now')
hardeningLDFlags+=('-z' 'now')
;;
*)
echo "Hardening flag unknown: $flag" >&2

View file

@ -237,8 +237,12 @@ stdenv.mkDerivation {
cat $out/nix-support/setup-hook.tmp >> $out/nix-support/setup-hook
rm $out/nix-support/setup-hook.tmp
substituteAll ${./add-flags} $out/nix-support/add-flags.sh
cp -p ${./add-hardening} $out/nix-support/add-hardening.sh
# some linkers on some platforms don't support -z
export ld_supports_bindnow=$([[ "$($ldPath/ld -z now 2>&1 || true)" =~ "un(known|recognized) option" ]])
export ld_supports_relro=$([[ "$($ldPath/ld -z relro 2>&1 || true)" =~ "un(known|recognized) option" ]])
substituteAll ${./add-flags.sh} $out/nix-support/add-flags.sh
substituteAll ${./add-hardening.sh} $out/nix-support/add-hardening.sh
cp -p ${./utils.sh} $out/nix-support/utils.sh
''
+ extraBuildCommands;

View file

@ -5,7 +5,7 @@ let
/* TODO: there are also MacOS, FreeBSD and Windows versions */
x86_64-linux = {
arch = "linuxx86";
sha256 = "07cny2qkzc624bzpdsy4iakcln0p7v5rhf8bv0vnh6rhpvnahrnq";
sha256 = "0g6mkl207ri3ib9w85i9w0sv7srz784pbxidz0d95p6qkvg6shba";
runtime = "lx86cl64";
kernel = "linuxx8664";
};

View file

@ -15,6 +15,8 @@ stdenv.mkDerivation rec {
# Needs to be propagated for the .pc file to work
propagatedBuildInputs = [ zeromq ];
NIX_CFLAGS_COMPILE = "-Wno-error=deprecated-declarations";
meta = with stdenv.lib; {
homepage = "http://czmq.zeromq.org/";
description = "High-level C Binding for ZeroMQ";

View file

@ -0,0 +1,51 @@
{ stdenv, fetchurl, gperf, guile, gmp, zlib, liboop, readline, gnum4, pam
, nettools, lsof, procps }:
stdenv.mkDerivation rec {
name = "lsh-2.0.4";
src = fetchurl {
url = "mirror://gnu/lsh/${name}.tar.gz";
sha256 = "614b9d63e13ad3e162c82b6405d1f67713fc622a8bc11337e72949d613713091";
};
patches = [ ./pam-service-name.patch ./lshd-no-root-login.patch ];
preConfigure = ''
# Patch `lsh-make-seed' so that it can gather enough entropy.
sed -i "src/lsh-make-seed.c" \
-e "s|/usr/sbin/arp|${nettools}/sbin/arp|g ;
s|/usr/bin/netstat|${nettools}/bin/netstat|g ;
s|/usr/local/bin/lsof|${lsof}/bin/lsof|g ;
s|/bin/vmstat|${procps}/bin/vmstat|g ;
s|/bin/ps|${procps}/bin/sp|g ;
s|/usr/bin/w|${procps}/bin/w|g ;
s|/usr/bin/df|$(type -P df)|g ;
s|/usr/bin/ipcs|$(type -P ipcs)|g ;
s|/usr/bin/uptime|$(type -P uptime)|g"
# Skip the `configure' script that checks whether /dev/ptmx & co. work as
# expected, because it relies on impurities (for instance, /dev/pts may
# be unavailable in chroots.)
export lsh_cv_sys_unix98_ptys=yes
'';
NIX_CFLAGS_COMPILE = "-std=gnu90";
buildInputs = [ gperf guile gmp zlib liboop readline gnum4 pam ];
meta = {
description = "GPL'd implementation of the SSH protocol";
longDescription = ''
lsh is a free implementation (in the GNU sense) of the ssh
version 2 protocol, currently being standardised by the IETF
SECSH working group.
'';
homepage = http://www.lysator.liu.se/~nisse/lsh/;
license = stdenv.lib.licenses.gpl2Plus;
maintainers = [ ];
platforms = [ "x86_64-linux" ];
};
}

View file

@ -0,0 +1,16 @@
Correctly handle the `--no-root-login' option.
--- lsh-2.0.4/src/lshd.c 2006-05-01 13:47:44.000000000 +0200
+++ lsh-2.0.4/src/lshd.c 2009-09-08 12:20:36.000000000 +0200
@@ -758,6 +758,10 @@ main_argp_parser(int key, char *arg, str
self->allow_root = 1;
break;
+ case OPT_NO_ROOT_LOGIN:
+ self->allow_root = 0;
+ break;
+
case OPT_KERBEROS_PASSWD:
self->pw_helper = PATH_KERBEROS_HELPER;
break;

View file

@ -0,0 +1,14 @@
Tell `lsh-pam-checkpw', the PAM password helper program, to use a more
descriptive service name.
--- lsh-2.0.4/src/lsh-pam-checkpw.c 2003-02-16 22:30:10.000000000 +0100
+++ lsh-2.0.4/src/lsh-pam-checkpw.c 2008-11-28 16:16:58.000000000 +0100
@@ -38,7 +38,7 @@
#include <security/pam_appl.h>
#define PWD_MAXLEN 1024
-#define SERVICE_NAME "other"
+#define SERVICE_NAME "lshd"
#define TIMEOUT 600
static int

View file

@ -2456,6 +2456,10 @@ in
lsb-release = callPackage ../os-specific/linux/lsb-release { };
# lsh installs `bin/nettle-lfib-stream' and so does Nettle. Give the
# former a lower priority than Nettle.
lsh = lowPrio (callPackage ../tools/networking/lsh { });
lshw = callPackage ../tools/system/lshw { };
lxc = callPackage ../os-specific/linux/lxc { };

View file

@ -56,6 +56,7 @@ in (mapTestOn {
guile = linux;
autogen = linux;
lsh = linux;
mailutils = linux;
mcron = linux;
texmacs = linux;

View file

@ -88,6 +88,7 @@ with import ./release-lib.nix { inherit supportedSystems; };
libxml2 = all;
libxslt = all;
lout = linux;
lsh = linux;
lsof = linux;
ltrace = linux;
lvm2 = linux;