Skip to content

Instantly share code, notes, and snippets.

@aszlig
Last active March 8, 2017 17:35
Show Gist options
  • Save aszlig/5e8c8462d17f787b7f171c34090fd590 to your computer and use it in GitHub Desktop.
Save aszlig/5e8c8462d17f787b7f171c34090fd590 to your computer and use it in GitHub Desktop.
{ debug ? false }:
let
pinnedNixpkgs = let
rev = "2839b101f927be5daab7948421de00a6f6c084ae";
url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz";
in fetchTarball url;
in import "${pinnedNixpkgs}/nixos/tests/make-test.nix" ({ pkgs, lib, ... }: {
name = "test-openssh-tun";
nodes = let
snakeoilKeyPair = import (pkgs.runCommand "snakeoil-keypair.nix" {
buildInputs = [ pkgs.openssh ];
} ''
ssh-keygen -t ed25519 -f key -N "" -C snakeoil-key
transform='$! { :l; N; $!bl; }; s/["\\$]/\\&/g; s/\n/\\n/g; p'
( echo "{"
echo " privateKey = \"$(sed -n -e "$transform" key)\\n\";"
echo " publicKey = \"$(sed -n -e "$transform" key.pub)\";"
echo "}"
) > "$out"
'');
common = { config, pkgs, ... }: {
boot.kernelModules = [ "tun" ];
networking.firewall.enable = false;
environment.systemPackages = [ config.boot.kernelPackages.perf ];
nixpkgs.config.packageOverrides = super: {
openssh = super.openssh.overrideDerivation (drv: {
patches = (drv.patches or []) ++ [ ./openssh-verbose.patch ];
});
};
};
client = {
imports = [ common ];
environment.etc.snakeoil = {
text = snakeoilKeyPair.privateKey;
mode = "0600";
};
};
server = { config, ... }: {
imports = [ common ];
services.openssh.enable = true;
services.openssh.extraConfig = ''
${lib.optionalString debug "LogLevel DEBUG3"}
PermitTunnel yes
'';
users.users.root.openssh.authorizedKeys = {
keys = lib.singleton snakeoilKeyPair.publicKey;
};
};
oldKernel.boot.kernelPackages = pkgs.linuxPackages_4_4;
in {
oldclient.imports = [ client oldKernel ];
oldserver.imports = [ server oldKernel ];
newclient = client;
newserver = server;
};
testScript = { nodes, ... }: let
localCommand = lib.concatStringsSep " && " [
"ip addr add 1.1.1.1/32 peer 2.2.2.2 dev tun1000"
"ip link set tun1000 up"
];
remoteCommand = lib.concatStringsSep " && " [
"ip addr add 2.2.2.2/32 peer 1.1.1.1 dev tun2000"
"ip link set tun2000 up"
];
perfie = pkgs.writeScript "perfie.sh" ''
#!${pkgs.stdenv.shell}
while [ ! -e /tmp/stop_perf ]; do sleep 1; done
touch /tmp/perf_stopped
'';
collectPerf = node: ''
''$${node}->execute('touch /tmp/stop_perf');
''$${node}->waitForFile('/tmp/perf_stopped');
''$${node}->execute('perf script >&2');
'';
startupAll = "startAll;" + lib.concatMapStrings (node: ''
''$${node}->waitForUnit('multi-user.target');
''$${node}->execute('ip monitor all >&2 &');
''$${node}->execute('perf probe -a dev_close >&2');
''$${node}->execute('perf record -a -R -g -e probe:* ${perfie} >&2 &');
'') (lib.attrNames nodes);
in startupAll + lib.concatMapStrings (prefix: let
client = "${prefix}client";
server = "${prefix}server";
kver = nodes.${client}.config.boot.kernelPackages.kernel.version;
perlEscape = lib.escape ["'"];
mkCmd = x: perlEscape (lib.concatMapStringsSep " " lib.escapeShellArg x);
execSSH = args: mkCmd ([ "ssh" ] ++ lib.optional debug "-vvv" ++ args);
in ''
subtest "checking with kernel version ${kver}", sub {
''$${client}->succeed('${execSSH [
"-i" "/etc/snakeoil"
"-o" "StrictHostKeyChecking=no"
"-o" "PermitLocalCommand=yes"
"-o" "LocalCommand=${localCommand}"
"-w" "1000:2000"
server remoteCommand
]} >&2 & perf trace -p $! >&2 &');
''$${client}->waitUntilSucceeds('ip link show tun1000');
''$${client}->sleep(5);
''$${client}->execute('ip link list >&2');
''$${server}->execute('ip link list >&2');
''$${client}->succeed('ping -c1 -s 512 2.2.2.2');
''$${server}->succeed('ping -c1 -s 512 1.1.1.1');
};
${collectPerf client}
${collectPerf server}
''$${client}->crash;
''$${server}->crash;
'') [ "old" "new" ];
}) {}
diff --git a/channels.c b/channels.c
index 398da9a8..e3519997 100644
--- a/channels.c
+++ b/channels.c
@@ -1734,6 +1734,8 @@ channel_handle_rfd(Channel *c, fd_set *readset, fd_set *writeset)
if (c->rfd != -1 && (force || FD_ISSET(c->rfd, readset))) {
errno = 0;
len = read(c->rfd, buf, sizeof(buf));
+ debug("channel %d read() returned %d, errno: %d",
+ c->self, len, errno);
if (len < 0 && (errno == EINTR ||
((errno == EAGAIN || errno == EWOULDBLOCK) && !force)))
return 1;
@@ -1805,6 +1807,8 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
if (c->datagram) {
/* ignore truncated writes, datagrams might get lost */
len = write(c->wfd, buf, dlen);
+ debug("channel %d write() returned %d, errno: %d",
+ c->self, len, errno);
free(data);
if (len < 0 && (errno == EINTR || errno == EAGAIN ||
errno == EWOULDBLOCK))
@@ -1825,6 +1829,8 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
#endif
len = write(c->wfd, buf, dlen);
+ debug("channel %d write() returned %d, errno: %d",
+ c->self, len, errno);
if (len < 0 &&
(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
return 1;
diff --git a/openbsd-compat/port-tun.c b/openbsd-compat/port-tun.c
index a444adf1..bd0387c7 100644
--- a/openbsd-compat/port-tun.c
+++ b/openbsd-compat/port-tun.c
@@ -194,6 +194,23 @@ sys_tun_open(int tun, int mode)
}
#endif /* SSH_TUN_FREEBSD */
+static void print_hex(u_char *buf, int len)
+{
+ int chars = 0, bpos = 0;
+ char pbuf[4096];
+ for (int i = 0; i < len; i++) {
+ snprintf(pbuf + bpos, 4096, "%02X ", *buf++);
+ bpos += 3;
+ if (++chars == 16 || i == len - 1) {
+ pbuf[bpos - 1] = '\0';
+ debug("> %s", pbuf);
+ bpos = 0;
+ pbuf[0] = '\0';
+ chars = 0;
+ }
+ }
+}
+
/*
* System-specific channel filters
*/
@@ -213,6 +230,9 @@ sys_tun_infilter(struct Channel *c, char *buf, int len)
char *ptr = buf;
int r;
+ debug("%d bytes from tun device to SSH channel:", len);
+ print_hex(buf, len);
+
#if defined(SSH_TUN_PREPEND_AF)
if (len <= 0 || len > (int)(sizeof(rbuf) - sizeof(*af)))
return (-1);
@@ -277,6 +297,9 @@ sys_tun_outfilter(struct Channel *c, u_char **data, u_int *dlen)
*af = htonl(AF_INET);
#endif
+ debug("%d bytes from SSH channel to tun device:", *dlen);
+ print_hex(buf, *dlen);
+
return (buf);
}
#endif /* SSH_TUN_FILTER */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment