Created
January 13, 2014 10:17
-
-
Save aszlig/8397726 to your computer and use it in GitHub Desktop.
Old version before OAuth could be used for HTTPS.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 34f081e38a0c6e41de03ca288c5717e95f7cf04b | |
Merge: 49c940b 7a6ada0 | |
Author: aszlig <[email protected]> | |
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 <[email protected]> | |
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 <[email protected]> | |
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 <[email protected]> | |
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 <[email protected]> | |
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 <[email protected]> | |
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 <[email protected]> | |
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="[email protected]"; | |
+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 <[email protected]> | |
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 <[email protected]> | |
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