Skip to content

Instantly share code, notes, and snippets.

@aszlig
Created January 13, 2014 10:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aszlig/8397726 to your computer and use it in GitHub Desktop.
Save aszlig/8397726 to your computer and use it in GitHub Desktop.
Old version before OAuth could be used for HTTPS.
commit 34f081e38a0c6e41de03ca288c5717e95f7cf04b
Merge: 49c940b 7a6ada0
Author: aszlig <aszlig@redmoonstudios.org>
Date: Wed Sep 19 16:47:33 2012 +0200
Merge branch 'ssh-multiplex'.
This now allows us to fetchgit from private GitHub repositories.
The procedure is somewhat complicated, as OpenSSH has a bunch of security checks
which prevent the nasty things we are doing here.
So in the end, we needed to patch OpenSSH to be somewhat less strict on checking
the user ID of the initiating process.
In order to properly use fetchgit with private Git repository, it is required to
do a `./github-access.sh start`, build the derivations (charon deploy) and
`./github-access.sh stop` if it is finished.
For production use I'd suggest we set up a timeout for the multiplexer so we
don't have an established connection to GitHub idling around. We don't want to
get banned/blocked by them, right?
commit 7a6ada0fc461737a03cac707d3298edf0fdaa205
Author: aszlig <aszlig@redmoonstudios.org>
Date: Wed Sep 19 16:42:48 2012 +0200
fetchrmsgit: Hook in SSH multiplexer Unix socket.
So, we finally hooked in the Unix domain socket and we should be ready to go for
agent-less SSH multiplexing. It only works for GitHub URLs right now, but that's
all that matters in the end.
Signed-off-by: aszlig <aszlig@redmoonstudios.org>
diff --git a/lib/fetchrmsgit.nix b/lib/fetchrmsgit.nix
index bf613ce..75b7e8d 100644
--- a/lib/fetchrmsgit.nix
+++ b/lib/fetchrmsgit.nix
@@ -1,8 +1,17 @@
-{ stdenv, fetchgit, openssh }:
+{ stdenv, fetchgit, writeScript, openssh }:
let
+ sshMasterSocket = (builtins.getEnv "HOME")
+ + "/.github_access/ssh_master.sock";
+
+ gitSSHCommand = writeScript "git-rms-ssh" ''
+ #!${stdenv.shell}
+ "${openssh}/bin/ssh" -o 'ControlPath "${sshMasterSocket}"' "$@"
+ '';
+
fetchgitOverride = original: {
buildInputs = original.buildInputs ++ [ openssh ];
+ GIT_SSH = gitSSHCommand;
};
fetchrmsgit = attrs: let
commit 5a046b77f90fd369838a03f921814343f3dab7a4
Author: aszlig <aszlig@redmoonstudios.org>
Date: Wed Sep 19 16:38:13 2012 +0200
github-access.sh: Provide patched OpenSSH.
After a quite long journey of writing an additional SSH proxy and to
reipmilement the SSH protocol to some extend, I remembered to take the simplest
approach:
Patching OpenSSH to ignore the effective user ID of the process from the Nix
builder.
I really didn't imagine that "patchin OpenSSH" would be the simplest solution,
but in our case, I'm afraid it is.
Signed-off-by: aszlig <aszlig@redmoonstudios.org>
diff --git a/bootstrap/openssh/default.nix b/bootstrap/openssh/default.nix
new file mode 100644
index 0000000..8b9a498
--- /dev/null
+++ b/bootstrap/openssh/default.nix
@@ -0,0 +1,5 @@
+let
+ pkgs = import <nixpkgs> {};
+in pkgs.lib.overrideDerivation pkgs.openssh (openssh: {
+ patches = openssh.patches ++ [ ./ignore_euid.patch ];
+})
diff --git a/bootstrap/openssh/ignore_euid.patch b/bootstrap/openssh/ignore_euid.patch
new file mode 100644
index 0000000..173899e
--- /dev/null
+++ b/bootstrap/openssh/ignore_euid.patch
@@ -0,0 +1,17 @@
+diff --git a/channels.c b/channels.c
+index 7791feb..89f3914 100644
+--- a/channels.c
++++ b/channels.c
+@@ -1936,12 +1936,6 @@ channel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset)
+ close(newsock);
+ return;
+ }
+- if ((euid != 0) && (getuid() != euid)) {
+- error("multiplex uid mismatch: peer euid %u != uid %u",
+- (u_int)euid, (u_int)getuid());
+- close(newsock);
+- return;
+- }
+ nc = channel_new("multiplex client", SSH_CHANNEL_MUX_CLIENT,
+ newsock, newsock, -1, c->local_window_max,
+ c->local_maxpacket, 0, "mux-control", 1);
diff --git a/github-access.sh b/github-access.sh
index 5743cae..b166890 100755
--- a/github-access.sh
+++ b/github-access.sh
@@ -10,9 +10,10 @@ socket_file="$socket_dir/ssh_master.sock";
do_ssh()
{
- ssh -o "ControlPath \"$socket_file\"" \
- -o "ControlPersist yes" \
- "$@";
+ ssh_out="$(nix-build --no-out-link bootstrap/openssh)";
+ "$ssh_out/bin/ssh" -o "ControlPath \"$socket_file\"" \
+ -o "ControlPersist yes" \
+ "$@";
}
do_chgrp()
@@ -57,7 +58,7 @@ case "$1" in
start)
if ! output="$(do_ssh -O check "$ssh_dest" 2>&1)";
then
- do_ssh -o "ControlMaster yes" -f -N -T "$ssh_dest";
+ do_ssh -f -M -N -T "$ssh_dest";
chmod 0666 "$socket_file";
else
echo "$output" >&2;
commit 6c487e0811d805f750636fcaaca4aa485671b83f
Author: aszlig <aszlig@redmoonstudios.org>
Date: Wed Sep 19 13:19:51 2012 +0200
github-access.sh: New script for SSH multiplexing.
This scripts sets up an SSH multiplexing daemon to github.com in order to relay
connections from the Nix worker.
Before starting this script for the first time, one has to run it with a 'setup'
argument in order to correctly set permissions so that the nix worker group is
able to access the socket file.
Signed-off-by: aszlig <aszlig@redmoonstudios.org>
diff --git a/github-access.sh b/github-access.sh
new file mode 100755
index 0000000..5743cae
--- /dev/null
+++ b/github-access.sh
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+ssh_dest="git@github.com";
+nix_worker_group="nixbld";
+
+# if you change any values here, be sure to change it in
+# lib/fetchrmsgit.nix as well.
+socket_dir="$HOME/.github_access";
+socket_file="$socket_dir/ssh_master.sock";
+
+do_ssh()
+{
+ ssh -o "ControlPath \"$socket_file\"" \
+ -o "ControlPersist yes" \
+ "$@";
+}
+
+do_chgrp()
+{
+ echo "Change the group of $1 to $nix_worker_group," >&2;
+ echo "trying with sudo:" >&2;
+ if sudo chgrp "$nix_worker_group" "$1";
+ then
+ echo "Succeeded with sudo." >&2;
+ else
+ echo "Failed with sudo, trying with su:" >&2;
+ su -c "chgrp \"$nix_worker_group\" \"$1\"";
+ fi;
+}
+
+fail_setup()
+{
+ echo -n "Setup failed, removing $socket_dir... " >&2;
+ rmdir "$socket_dir";
+ echo "done." >&2;
+}
+
+do_setup()
+{
+ if [ -d "$socket_dir" ];
+ then
+ echo "Socket directory $socket_dir" >&2;
+ echo "already exists, so if you want to set up from" >&2;
+ echo "scratch, please remove the directory and run" >&2;
+ echo "this script again." >&2;
+ return 1;
+ fi;
+
+ mkdir -p "$socket_dir" || fail_setup;
+ do_chgrp "$socket_dir" || fail_setup;
+ chmod 0750 "$socket_dir" || fail_setup;
+
+ echo "Setup done." >&2;
+}
+
+case "$1" in
+ start)
+ if ! output="$(do_ssh -O check "$ssh_dest" 2>&1)";
+ then
+ do_ssh -o "ControlMaster yes" -f -N -T "$ssh_dest";
+ chmod 0666 "$socket_file";
+ else
+ echo "$output" >&2;
+ fi;
+ ;;
+ status)
+ do_ssh -O check "$ssh_dest";
+ ;;
+ stop)
+ do_ssh -O exit "$ssh_dest";
+ ;;
+ setup)
+ do_setup;
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|status|setup}" >&2;
+ echo " Open a new SSH multiplexing session to GitHub." >&2;
+ echo " This is in order to allow fetching private Git" >&2;
+ echo " repositories." >&2;
+ echo >&2;
+ echo " This script can be used just like any system V" >&2;
+ echo " init script. But in order to be useful, you have" >&2;
+ echo " to run the 'setup' subcommand in order to set up" >&2;
+ echo " a directory in your home directory having the" >&2;
+ echo " right privileges so that only the nix worker is" >&2;
+ echo " able to access your multiplexed connection." >&2;
+ echo >&2;
+ echo " Please note, that the 'setup' subcommand will" >&2;
+ echo " try to use 'sudo' first and fall back to 'su'" >&2;
+ echo " if 'sudo' fails or is unavailable." >&2;
+ echo >&2;
+ echo " This step is needed because only the superuser" >&2;
+ echo " has the sufficient privileges to change the" >&2;
+ echo " group ownership of files." >&2;
+ ;;
+esac;
commit 49c940be95ea44f5faf5d7bc4b717120e96be8b5
Author: aszlig <aszlig@redmoonstudios.org>
Date: Wed Sep 19 10:42:57 2012 +0200
Add basic fetchgit ovveride 'fetchrmsgit'.
This override just adds openssh to the buildInputs attribute, so we at least
have SSH available while git is trying to fetch one of our private repositories.
Unfortunately this will still fail, because SSH is not able to find the correct
private key.
Signed-off-by: aszlig <aszlig@redmoonstudios.org>
diff --git a/lib/fetchrmsgit.nix b/lib/fetchrmsgit.nix
new file mode 100644
index 0000000..bf613ce
--- /dev/null
+++ b/lib/fetchrmsgit.nix
@@ -0,0 +1,11 @@
+{ stdenv, fetchgit, openssh }:
+
+let
+ fetchgitOverride = original: {
+ buildInputs = original.buildInputs ++ [ openssh ];
+ };
+
+ fetchrmsgit = attrs: let
+ result = fetchgit attrs;
+ in stdenv.lib.overrideDerivation result fetchgitOverride;
+in fetchrmsgit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment