From e1aac98bf51982e1bb7cbe61f9af8f0774f4ce6f Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Sat, 20 Dec 2014 12:57:15 +0100 Subject: Add sshd setup instructions Signed-off-by: Lukas Fleischer --- INSTALL | 108 ++++----------- .../0001-Patch-sshd-for-the-AUR.patch | 152 +++++++++++++++++++++ scripts/git-integration/sshd_config | 6 + 3 files changed, 185 insertions(+), 81 deletions(-) create mode 100644 scripts/git-integration/0001-Patch-sshd-for-the-AUR.patch create mode 100644 scripts/git-integration/sshd_config diff --git a/INSTALL b/INSTALL index cbb9f44..b198997 100644 --- a/INSTALL +++ b/INSTALL @@ -1,96 +1,42 @@ -Setup on Arch Linux: -==================== -1) Install Apache, MySQL, PHP, git and php-pear - # pacman -Syu apache mysql php git php-pear +Setup on Arch Linux +=================== -2) Set a local 'hostname' of 'aur' - - Edit /etc/hosts and append 'aur' to loopback address - 127.0.0.1 localhost aur +1) Clone the AUR project: -3) Configure Apache - - - Edit /etc/httpd/conf/httpd.conf and enable PHP support - by adding the following lines. - - LoadModule php5_module modules/libphp5.so - Include conf/extra/php5_module.conf - - - Also append the following snippet to enable the aur - Virtual Host in /etc/httpd/conf/extra/httpd-vhosts.conf. - Comment out the example vhosts and replace MYUSER with your username. - (You could put aur in /srv/http/aur and then create a symlink in ~ ) - - - Servername aur - DocumentRoot /home/MYUSER/aur/web/html - ErrorLog /var/log/httpd/aur-error.log - CustomLog /var/log/httpd/aur-access.log combined - - Options Indexes FollowSymLinks - AllowOverride All - Order allow,deny - Allow from all - - - - - In httpd.conf, uncomment this line: - - Include conf/extra/httpd-vhosts.conf - -4) Clone the AUR project (using the MYUSER from above) - $ cd + $ cd /srv/http/ $ git clone git://projects.archlinux.org/aur.git -5) Configure PHP - Make sure you have mysql and json enabled in PHP. - - - Edit php.ini and uncomment/add this line: - extension=pdo_mysql.so - - If this PHP extension is a separate package on your system, install it. +2) Setup a web server with PHP and MySQL. -6) Configure MySQL - - Start the MySQL service. Example: - # systemctl start mysqld +3) Copy conf/config.proto to conf/config and adjust the configuration. - - Create database - # mysqladmin -p create AUR +4) Create a new MySQL database and a user and import the AUR SQL schema: - - Connect to the mysql client - $ mysql -uroot -p AUR + $ mysql -uaur -p AUR GRANT ALL PRIVILEGES ON AUR.* to aur@localhost - -> identified by 'aur'; - mysql> FLUSH PRIVILEGES; - mysql> quit +5) Clone the OpenSSH project, apply the AUR sshd patch and run `make`: - - Load the schema file - $ mysql -uaur -p AUR < ~/aur/schema/aur-schema.sql - (give password 'aur' at the prompt) + $ cd /srv/http/aur/ + $ git clone git://anongit.mindrot.org/openssh.git + $ cd openssh + $ git am ../scripts/git-integration/0001-Patch-sshd-for-the-AUR.patch + $ autoreconf + $ ./configure + $ make - - Optionally load some test data for development purposes. - # pacman -S words fortune-mod - $ cd ~/aur/schema/ - $ python gendummydata.py dummy-data.sql - $ bzip2 dummy-data.sql - $ bzcat dummy-data.sql.bz2 | mysql -uaur -p AUR - (give password 'aur' at the prompt) +6) Create and edit the sshd configuration: - If your test data consists of real people and real email addresses consider - inserting bogus addressess to avoid sending unwanted spam from testing. You - can insert garbage addresses with: - mysql> UPDATE Users SET Email = RAND() * RAND(); + $ cd /srv/http/aur/ + $ umask 077 + $ mkdir .ssh/ + $ ssh-keygen -f .ssh/ssh_host_rsa_key -N '' -t rsa + $ cp scripts/git-integration/sshd_config .ssh/ -7) Copy the config.inc.php.proto file to config.inc.php. Modify as needed. - $ cd ~/aur/web/lib/ - $ cp config.inc.php.proto config.inc.php +7) Create a new user and change ownership of the .ssh directory: - In case you set $USE_VIRTUAL_URLS to true (default nowadays) you should add - a rewrite rule. For Apache, add this ~/aur/web/html/.htaccess: + # useradd -U -d /srv/http/aur -c 'AUR user' aur + # chown aur:aur /srv/http/aur/.ssh/ - RewriteEngine on - RewriteCond %{REQUEST_URI} !^/index.php - RewriteRule ^(.*)$ /index.php/$1 +8) Run the sshd as the new user. -8) Point your browser to http://aur + $ /srv/http/aur/openssh/sshd -f /srv/http/aur/.ssh/sshd_config diff --git a/scripts/git-integration/0001-Patch-sshd-for-the-AUR.patch b/scripts/git-integration/0001-Patch-sshd-for-the-AUR.patch new file mode 100644 index 0000000..6b72712 --- /dev/null +++ b/scripts/git-integration/0001-Patch-sshd-for-the-AUR.patch @@ -0,0 +1,152 @@ +From e23745b61a46f034bca3cab9936c24c249afdc7f Mon Sep 17 00:00:00 2001 +From: Lukas Fleischer +Date: Sun, 21 Dec 2014 22:17:48 +0100 +Subject: [PATCH] Patch sshd for the AUR + +* Add SSH_KEY_FINGERPRINT and SSH_KEY variables to the environment of + the AuthorizedKeysCommand which allows for efficiently looking up SSH + keys in the AUR database. + +* Remove the secure path check for the AuthorizedKeysCommand. We are + running the sshd under a non-privileged user who has as little + permissions as possible. In particular, he does not own the directory + that contains the scripts for the Git backend. + +* Prevent from running the sshd as root. + +Signed-off-by: Lukas Fleischer +--- + auth2-pubkey.c | 48 +++++++++++++++++++++++++++++++++++++++++++----- + ssh.h | 12 ++++++++++++ + sshd.c | 5 +++++ + sshd_config.5 | 5 +++++ + 4 files changed, 65 insertions(+), 5 deletions(-) + +diff --git a/auth2-pubkey.c b/auth2-pubkey.c +index 0a3c1de..baf4922 100644 +--- a/auth2-pubkey.c ++++ b/auth2-pubkey.c +@@ -510,6 +510,8 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key) + int status, devnull, p[2], i; + pid_t pid; + char *username, errmsg[512]; ++ struct sshbuf *b = NULL, *bb = NULL; ++ char *keytext, *uu = NULL; + + if (options.authorized_keys_command == NULL || + options.authorized_keys_command[0] != '/') +@@ -538,11 +540,6 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key) + options.authorized_keys_command, strerror(errno)); + goto out; + } +- if (auth_secure_path(options.authorized_keys_command, &st, NULL, 0, +- errmsg, sizeof(errmsg)) != 0) { +- error("Unsafe AuthorizedKeysCommand: %s", errmsg); +- goto out; +- } + + if (pipe(p) != 0) { + error("%s: pipe: %s", __func__, strerror(errno)); +@@ -568,6 +565,47 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key) + for (i = 0; i < NSIG; i++) + signal(i, SIG_DFL); + ++ keytext = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); ++ if (setenv(SSH_KEY_FINGERPRINT_ENV_NAME, keytext, 1) == -1) { ++ error("%s: setenv: %s", __func__, strerror(errno)); ++ _exit(1); ++ } ++ ++ if (!(b = sshbuf_new()) || !(bb = sshbuf_new())) { ++ error("%s: sshbuf_new: %s", __func__, strerror(errno)); ++ _exit(1); ++ } ++ if (sshkey_to_blob_buf(key, bb) != 0) { ++ error("%s: sshkey_to_blob_buf: %s", __func__, ++ strerror(errno)); ++ _exit(1); ++ } ++ if (!(uu = sshbuf_dtob64(bb))) { ++ error("%s: sshbuf_dtob64: %s", __func__, ++ strerror(errno)); ++ _exit(1); ++ } ++ if (sshbuf_putf(b, "%s ", sshkey_ssh_name(key))) { ++ error("%s: sshbuf_putf: %s", __func__, ++ strerror(errno)); ++ _exit(1); ++ } ++ if (sshbuf_put(b, uu, strlen(uu) + 1)) { ++ error("%s: sshbuf_put: %s", __func__, ++ strerror(errno)); ++ _exit(1); ++ } ++ if (setenv(SSH_KEY_ENV_NAME, sshbuf_ptr(b), 1) == -1) { ++ error("%s: setenv: %s", __func__, strerror(errno)); ++ _exit(1); ++ } ++ if (uu) ++ free(uu); ++ if (b) ++ sshbuf_free(b); ++ if (bb) ++ sshbuf_free(bb); ++ + if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { + error("%s: open %s: %s", __func__, _PATH_DEVNULL, + strerror(errno)); +diff --git a/ssh.h b/ssh.h +index c94633b..411ea86 100644 +--- a/ssh.h ++++ b/ssh.h +@@ -97,3 +97,15 @@ + + /* Listen backlog for sshd, ssh-agent and forwarding sockets */ + #define SSH_LISTEN_BACKLOG 128 ++ ++/* ++ * Name of the environment variable containing the incoming key passed ++ * to AuthorizedKeysCommand. ++ */ ++#define SSH_KEY_ENV_NAME "SSH_KEY" ++ ++/* ++ * Name of the environment variable containing the incoming key fingerprint ++ * passed to AuthorizedKeysCommand. ++ */ ++#define SSH_KEY_FINGERPRINT_ENV_NAME "SSH_KEY_FINGERPRINT" +diff --git a/sshd.c b/sshd.c +index 4e01855..60c676f 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -1424,6 +1424,11 @@ main(int ac, char **av) + av = saved_argv; + #endif + ++ if (geteuid() == 0) { ++ fprintf(stderr, "this is a patched version of the sshd that must not be run as root.\n"); ++ exit(1); ++ } ++ + if (geteuid() == 0 && setgroups(0, NULL) == -1) + debug("setgroups(): %.200s", strerror(errno)); + +diff --git a/sshd_config.5 b/sshd_config.5 +index ef36d33..1d7bade 100644 +--- a/sshd_config.5 ++++ b/sshd_config.5 +@@ -223,6 +223,11 @@ It will be invoked with a single argument of the username + being authenticated, and should produce on standard output zero or + more lines of authorized_keys output (see AUTHORIZED_KEYS in + .Xr sshd 8 ) . ++The key being used for authentication (the key's type and the key text itself, ++separated by a space) will be available in the ++.Ev SSH_KEY ++environment variable, and the fingerprint of the key will be available in the ++.Ev SSH_KEY_FINGERPRINT environment variable. + If a key supplied by AuthorizedKeysCommand does not successfully authenticate + and authorize the user then public key authentication continues using the usual + .Cm AuthorizedKeysFile +-- +2.2.1 + diff --git a/scripts/git-integration/sshd_config b/scripts/git-integration/sshd_config new file mode 100644 index 0000000..fbe3578 --- /dev/null +++ b/scripts/git-integration/sshd_config @@ -0,0 +1,6 @@ +Port 2222 +HostKey ~/.ssh/ssh_host_rsa_key +PasswordAuthentication no +UsePrivilegeSeparation no +AuthorizedKeysCommand /srv/http/aur/scripts/git-integration/git-auth.py +AuthorizedKeysCommandUser aur -- cgit v1.2.3-54-g00ecf