1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-27 16:00:59 +01:00
phorge-phorge/scripts/ssh/ssh-auth-key.php

42 lines
920 B
PHP
Raw Normal View History

Prepare to route VCS connections through SSH Summary: Fixes T2229. This sets the stage for a patch similar to D7417, but for SSH. In particular, SSH 6.2 introduced an `AuthorizedKeysCommand` directive, which lets us do this in a mostly-reasonable way without needing users to patch sshd (if they have a recent enough version, at least). The way the `AuthorizedKeysCommand` works is that it gets run and produces an `authorized_keys`-style file fragment. This isn't ideal, because we have to dump every key into the result, but should be fine for most installs. The earlier patch against `sshd` passes the public key itself, which allows the script to just look up the key. We might use this eventually, since it can scale much better, so I haven't removed it. Generally, auth is split into two scripts now which mostly do the same thing: - `ssh-auth` is the AuthorizedKeysCommand auth, which takes nothing and dumps the whole keyfile. - `ssh-auth-key` is the slightly cleaner and more scalable (but patch-dependent) version, which takes the public key and dumps only matching options. I also reworked the argument parsing to be a bit more sane. Test Plan: This is somewhat-intentionally a bit obtuse since I don't really want anyone using it yet, but basically: - Copy `phabricator-ssh-hook.sh` to somewhere like `/usr/libexec/openssh/`, chown it `root` and chmod it `500`. - This script should probably also do a username check in the future. - Create a copy of `sshd_config` and fix the paths/etc. Point the KeyScript at your copy of the hook. - Start a copy of sshd (6.2 or newer) with `-f <your config file>` and maybe `-d -d -d` to foreground and debug. - Run `ssh -p 2222 localhost` or similar. Specifically, I did this setup and then ran a bunch of commands like: - `ssh host` (denied, no command) - `ssh host ls` (denied, not supported) - `echo '{}' | ssh host conduit conduit.ping` (works) Reviewers: btrahan Reviewed By: btrahan CC: hach-que, aran Maniphest Tasks: T2229, T2230 Differential Revision: https://secure.phabricator.com/D7419
2013-10-26 18:43:43 +02:00
#!/usr/bin/env php
<?php
$root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/__init_script__.php';
Add a query/policy layer on top of SSH keys for Almanac Summary: Ref T5833. Currently, SSH keys are associated only with users, and are a bit un-modern. I want to let Almanac Devices have SSH keys so devices in a cluster can identify to one another. For example, with hosted installs, initialization will go something like this: - A request comes in for `company.phacility.com`. - A SiteSource (from D10787) makes a Conduit call to Almanac on the master install to check if `company` is a valid install and pull config if it is. - This call can be signed with an SSH key which identifies a trusted Almanac Device. In the cluster case, a web host can make an authenticated call to a repository host with similar key signing. To move toward this, put a proper Query class on top of SSH key access (this diff). In following diffs, I'll: - Rename `userPHID` to `objectPHID`. - Move this to the `auth` database. - Provide UI for device/key association. An alternative approach would be to build some kind of special token layer in Conduit, but I think that would be a lot harder to manage in the hosting case. This gives us a more direct attack on trusting requests from machines and recognizing machines as first (well, sort of second-class) actors without needing things like fake user accounts. Test Plan: - Added and removed SSH keys. - Added and removed SSH keys from a bot account. - Tried to edit an unonwned SSH key (denied). - Ran `bin/ssh-auth`, got sensible output. - Ran `bin/ssh-auth-key`, got sensible output. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T5833 Differential Revision: https://secure.phabricator.com/D10790
2014-11-06 21:37:02 +01:00
try {
$cert = file_get_contents('php://stdin');
$public_key = PhabricatorAuthSSHPublicKey::newFromRawKey($cert);
} catch (Exception $ex) {
Prepare to route VCS connections through SSH Summary: Fixes T2229. This sets the stage for a patch similar to D7417, but for SSH. In particular, SSH 6.2 introduced an `AuthorizedKeysCommand` directive, which lets us do this in a mostly-reasonable way without needing users to patch sshd (if they have a recent enough version, at least). The way the `AuthorizedKeysCommand` works is that it gets run and produces an `authorized_keys`-style file fragment. This isn't ideal, because we have to dump every key into the result, but should be fine for most installs. The earlier patch against `sshd` passes the public key itself, which allows the script to just look up the key. We might use this eventually, since it can scale much better, so I haven't removed it. Generally, auth is split into two scripts now which mostly do the same thing: - `ssh-auth` is the AuthorizedKeysCommand auth, which takes nothing and dumps the whole keyfile. - `ssh-auth-key` is the slightly cleaner and more scalable (but patch-dependent) version, which takes the public key and dumps only matching options. I also reworked the argument parsing to be a bit more sane. Test Plan: This is somewhat-intentionally a bit obtuse since I don't really want anyone using it yet, but basically: - Copy `phabricator-ssh-hook.sh` to somewhere like `/usr/libexec/openssh/`, chown it `root` and chmod it `500`. - This script should probably also do a username check in the future. - Create a copy of `sshd_config` and fix the paths/etc. Point the KeyScript at your copy of the hook. - Start a copy of sshd (6.2 or newer) with `-f <your config file>` and maybe `-d -d -d` to foreground and debug. - Run `ssh -p 2222 localhost` or similar. Specifically, I did this setup and then ran a bunch of commands like: - `ssh host` (denied, no command) - `ssh host ls` (denied, not supported) - `echo '{}' | ssh host conduit conduit.ping` (works) Reviewers: btrahan Reviewed By: btrahan CC: hach-que, aran Maniphest Tasks: T2229, T2230 Differential Revision: https://secure.phabricator.com/D7419
2013-10-26 18:43:43 +02:00
exit(1);
}
Add a query/policy layer on top of SSH keys for Almanac Summary: Ref T5833. Currently, SSH keys are associated only with users, and are a bit un-modern. I want to let Almanac Devices have SSH keys so devices in a cluster can identify to one another. For example, with hosted installs, initialization will go something like this: - A request comes in for `company.phacility.com`. - A SiteSource (from D10787) makes a Conduit call to Almanac on the master install to check if `company` is a valid install and pull config if it is. - This call can be signed with an SSH key which identifies a trusted Almanac Device. In the cluster case, a web host can make an authenticated call to a repository host with similar key signing. To move toward this, put a proper Query class on top of SSH key access (this diff). In following diffs, I'll: - Rename `userPHID` to `objectPHID`. - Move this to the `auth` database. - Provide UI for device/key association. An alternative approach would be to build some kind of special token layer in Conduit, but I think that would be a lot harder to manage in the hosting case. This gives us a more direct attack on trusting requests from machines and recognizing machines as first (well, sort of second-class) actors without needing things like fake user accounts. Test Plan: - Added and removed SSH keys. - Added and removed SSH keys from a bot account. - Tried to edit an unonwned SSH key (denied). - Ran `bin/ssh-auth`, got sensible output. - Ran `bin/ssh-auth-key`, got sensible output. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T5833 Differential Revision: https://secure.phabricator.com/D10790
2014-11-06 21:37:02 +01:00
$key = id(new PhabricatorAuthSSHKeyQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withKeys(array($public_key))
->executeOne();
if (!$key) {
Prepare to route VCS connections through SSH Summary: Fixes T2229. This sets the stage for a patch similar to D7417, but for SSH. In particular, SSH 6.2 introduced an `AuthorizedKeysCommand` directive, which lets us do this in a mostly-reasonable way without needing users to patch sshd (if they have a recent enough version, at least). The way the `AuthorizedKeysCommand` works is that it gets run and produces an `authorized_keys`-style file fragment. This isn't ideal, because we have to dump every key into the result, but should be fine for most installs. The earlier patch against `sshd` passes the public key itself, which allows the script to just look up the key. We might use this eventually, since it can scale much better, so I haven't removed it. Generally, auth is split into two scripts now which mostly do the same thing: - `ssh-auth` is the AuthorizedKeysCommand auth, which takes nothing and dumps the whole keyfile. - `ssh-auth-key` is the slightly cleaner and more scalable (but patch-dependent) version, which takes the public key and dumps only matching options. I also reworked the argument parsing to be a bit more sane. Test Plan: This is somewhat-intentionally a bit obtuse since I don't really want anyone using it yet, but basically: - Copy `phabricator-ssh-hook.sh` to somewhere like `/usr/libexec/openssh/`, chown it `root` and chmod it `500`. - This script should probably also do a username check in the future. - Create a copy of `sshd_config` and fix the paths/etc. Point the KeyScript at your copy of the hook. - Start a copy of sshd (6.2 or newer) with `-f <your config file>` and maybe `-d -d -d` to foreground and debug. - Run `ssh -p 2222 localhost` or similar. Specifically, I did this setup and then ran a bunch of commands like: - `ssh host` (denied, no command) - `ssh host ls` (denied, not supported) - `echo '{}' | ssh host conduit conduit.ping` (works) Reviewers: btrahan Reviewed By: btrahan CC: hach-que, aran Maniphest Tasks: T2229, T2230 Differential Revision: https://secure.phabricator.com/D7419
2013-10-26 18:43:43 +02:00
exit(1);
}
Add a query/policy layer on top of SSH keys for Almanac Summary: Ref T5833. Currently, SSH keys are associated only with users, and are a bit un-modern. I want to let Almanac Devices have SSH keys so devices in a cluster can identify to one another. For example, with hosted installs, initialization will go something like this: - A request comes in for `company.phacility.com`. - A SiteSource (from D10787) makes a Conduit call to Almanac on the master install to check if `company` is a valid install and pull config if it is. - This call can be signed with an SSH key which identifies a trusted Almanac Device. In the cluster case, a web host can make an authenticated call to a repository host with similar key signing. To move toward this, put a proper Query class on top of SSH key access (this diff). In following diffs, I'll: - Rename `userPHID` to `objectPHID`. - Move this to the `auth` database. - Provide UI for device/key association. An alternative approach would be to build some kind of special token layer in Conduit, but I think that would be a lot harder to manage in the hosting case. This gives us a more direct attack on trusting requests from machines and recognizing machines as first (well, sort of second-class) actors without needing things like fake user accounts. Test Plan: - Added and removed SSH keys. - Added and removed SSH keys from a bot account. - Tried to edit an unonwned SSH key (denied). - Ran `bin/ssh-auth`, got sensible output. - Ran `bin/ssh-auth-key`, got sensible output. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T5833 Differential Revision: https://secure.phabricator.com/D10790
2014-11-06 21:37:02 +01:00
$object = $key->getObject();
if (!($object instanceof PhabricatorUser)) {
Prepare to route VCS connections through SSH Summary: Fixes T2229. This sets the stage for a patch similar to D7417, but for SSH. In particular, SSH 6.2 introduced an `AuthorizedKeysCommand` directive, which lets us do this in a mostly-reasonable way without needing users to patch sshd (if they have a recent enough version, at least). The way the `AuthorizedKeysCommand` works is that it gets run and produces an `authorized_keys`-style file fragment. This isn't ideal, because we have to dump every key into the result, but should be fine for most installs. The earlier patch against `sshd` passes the public key itself, which allows the script to just look up the key. We might use this eventually, since it can scale much better, so I haven't removed it. Generally, auth is split into two scripts now which mostly do the same thing: - `ssh-auth` is the AuthorizedKeysCommand auth, which takes nothing and dumps the whole keyfile. - `ssh-auth-key` is the slightly cleaner and more scalable (but patch-dependent) version, which takes the public key and dumps only matching options. I also reworked the argument parsing to be a bit more sane. Test Plan: This is somewhat-intentionally a bit obtuse since I don't really want anyone using it yet, but basically: - Copy `phabricator-ssh-hook.sh` to somewhere like `/usr/libexec/openssh/`, chown it `root` and chmod it `500`. - This script should probably also do a username check in the future. - Create a copy of `sshd_config` and fix the paths/etc. Point the KeyScript at your copy of the hook. - Start a copy of sshd (6.2 or newer) with `-f <your config file>` and maybe `-d -d -d` to foreground and debug. - Run `ssh -p 2222 localhost` or similar. Specifically, I did this setup and then ran a bunch of commands like: - `ssh host` (denied, no command) - `ssh host ls` (denied, not supported) - `echo '{}' | ssh host conduit conduit.ping` (works) Reviewers: btrahan Reviewed By: btrahan CC: hach-que, aran Maniphest Tasks: T2229, T2230 Differential Revision: https://secure.phabricator.com/D7419
2013-10-26 18:43:43 +02:00
exit(1);
}
$bin = $root.'/bin/ssh-exec';
Add a query/policy layer on top of SSH keys for Almanac Summary: Ref T5833. Currently, SSH keys are associated only with users, and are a bit un-modern. I want to let Almanac Devices have SSH keys so devices in a cluster can identify to one another. For example, with hosted installs, initialization will go something like this: - A request comes in for `company.phacility.com`. - A SiteSource (from D10787) makes a Conduit call to Almanac on the master install to check if `company` is a valid install and pull config if it is. - This call can be signed with an SSH key which identifies a trusted Almanac Device. In the cluster case, a web host can make an authenticated call to a repository host with similar key signing. To move toward this, put a proper Query class on top of SSH key access (this diff). In following diffs, I'll: - Rename `userPHID` to `objectPHID`. - Move this to the `auth` database. - Provide UI for device/key association. An alternative approach would be to build some kind of special token layer in Conduit, but I think that would be a lot harder to manage in the hosting case. This gives us a more direct attack on trusting requests from machines and recognizing machines as first (well, sort of second-class) actors without needing things like fake user accounts. Test Plan: - Added and removed SSH keys. - Added and removed SSH keys from a bot account. - Tried to edit an unonwned SSH key (denied). - Ran `bin/ssh-auth`, got sensible output. - Ran `bin/ssh-auth-key`, got sensible output. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T5833 Differential Revision: https://secure.phabricator.com/D10790
2014-11-06 21:37:02 +01:00
$cmd = csprintf('%s --phabricator-ssh-user %s', $bin, $object->getUsername());
Prepare to route VCS connections through SSH Summary: Fixes T2229. This sets the stage for a patch similar to D7417, but for SSH. In particular, SSH 6.2 introduced an `AuthorizedKeysCommand` directive, which lets us do this in a mostly-reasonable way without needing users to patch sshd (if they have a recent enough version, at least). The way the `AuthorizedKeysCommand` works is that it gets run and produces an `authorized_keys`-style file fragment. This isn't ideal, because we have to dump every key into the result, but should be fine for most installs. The earlier patch against `sshd` passes the public key itself, which allows the script to just look up the key. We might use this eventually, since it can scale much better, so I haven't removed it. Generally, auth is split into two scripts now which mostly do the same thing: - `ssh-auth` is the AuthorizedKeysCommand auth, which takes nothing and dumps the whole keyfile. - `ssh-auth-key` is the slightly cleaner and more scalable (but patch-dependent) version, which takes the public key and dumps only matching options. I also reworked the argument parsing to be a bit more sane. Test Plan: This is somewhat-intentionally a bit obtuse since I don't really want anyone using it yet, but basically: - Copy `phabricator-ssh-hook.sh` to somewhere like `/usr/libexec/openssh/`, chown it `root` and chmod it `500`. - This script should probably also do a username check in the future. - Create a copy of `sshd_config` and fix the paths/etc. Point the KeyScript at your copy of the hook. - Start a copy of sshd (6.2 or newer) with `-f <your config file>` and maybe `-d -d -d` to foreground and debug. - Run `ssh -p 2222 localhost` or similar. Specifically, I did this setup and then ran a bunch of commands like: - `ssh host` (denied, no command) - `ssh host ls` (denied, not supported) - `echo '{}' | ssh host conduit conduit.ping` (works) Reviewers: btrahan Reviewed By: btrahan CC: hach-que, aran Maniphest Tasks: T2229, T2230 Differential Revision: https://secure.phabricator.com/D7419
2013-10-26 18:43:43 +02:00
// This is additional escaping for the SSH 'command="..."' string.
$cmd = addcslashes($cmd, '"\\');
$options = array(
'command="'.$cmd.'"',
'no-port-forwarding',
'no-X11-forwarding',
'no-agent-forwarding',
'no-pty',
);
echo implode(',', $options);
exit(0);