From: Aurelien Jarno Date: Thu, 13 Aug 2015 21:19:16 +0000 (+0200) Subject: add ssh-wrapper + userkeys config for buildd rsync uploads X-Git-Url: https://git.donarmstrong.com/?p=dsa-puppet.git;a=commitdiff_plain;h=6a94b204599f27a5ec786e03242b594fb51bc7fc add ssh-wrapper + userkeys config for buildd rsync uploads This should allow the buildds to do uploads using rsync to ssh.upload.d.o:/srv/upload.debian.org/UploadQueue/ Signed-off-by: Aurelien Jarno --- diff --git a/hieradata/common.yaml b/hieradata/common.yaml index 7ef02e07..913a6c93 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -101,6 +101,8 @@ roles: - wolkenstein.debian.org search_frontend: - cgi-grnet-01.debian.org + ssh.upload.d.o: + - coccia.debian.org sso: - diabelli.debian.org static_master: diff --git a/modules/roles/files/ssh_upload/rsync-ssh-wrap b/modules/roles/files/ssh_upload/rsync-ssh-wrap new file mode 100755 index 00000000..8f3e8d89 --- /dev/null +++ b/modules/roles/files/ssh_upload/rsync-ssh-wrap @@ -0,0 +1,109 @@ +#!/bin/bash + +# Copyright (c) 2009, 2010, 2012 Peter Palfrader +# Copyright (c) 2015 Aurelien Jarno +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +set -e +set -u + +MYLOGNAME="`basename "$0"`[$$]" +RSYNCDIR="/srv/upload.debian.org/UploadQueue/" + +usage() { + echo "local Usage: $0 " + echo "via ssh orig command: rsync " +} + +one_more_arg() { + if [ "$#" -lt 1 ]; then + usage >&2 + exit 1 + fi +} + +info() { + logger -p daemon.info -t "$MYLOGNAME" "$1" +} + +croak() { + logger -s -p daemon.warn -t "$MYLOGNAME" "$1" + exit 1 +} + +do_rsync() { + local remote_host="$1" + shift + + local allowed_rsyncs + allowed_rsyncs=() + + if [ -d "$RSYNCDIR" ]; then + allowed_rsyncs+=("--server -vlogDtprxze.iLsf --partial . $RSYNCDIR") # wheezy + allowed_rsyncs+=("--server -vlogDtprxze.iLsfx --partial . $RSYNCDIR") # jessie + fi + for cmd_idx in ${!allowed_rsyncs[*]}; do + allowed="${allowed_rsyncs[$cmd_idx]}" + if [ "$*" = "$allowed" ]; then + info "Running for host $remote_host: rsync $*" + exec rsync "$@" + croak "Exec failed" + fi + done + + info "NOT allowed for $remote_host: rsync $*" + echo >&2 "This rsync command ($@) not allowed." + exit 1 +} + +if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then + usage + exit 0 +fi + +one_more_arg "$@" +remote_host="$1" +shift + + +# check/parse remote command line +if [ -z "${SSH_ORIGINAL_COMMAND:-}" ] ; then + croak "Did not find SSH_ORIGINAL_COMMAND" +fi +set "dummy" ${SSH_ORIGINAL_COMMAND} +shift + +info "host $remote_host called with $*" + +one_more_arg "$@" +action="$1" +shift + +case "$action" in + # rsync command to upload packages + rsync) + do_rsync "$remote_host" "$@" + ;; + # just ignore any other commands (e.g. chmod) + *) + info "Ignored operation '$action'" + ;; +esac diff --git a/modules/roles/manifests/init.pp b/modules/roles/manifests/init.pp index edf4d3e9..4c866847 100644 --- a/modules/roles/manifests/init.pp +++ b/modules/roles/manifests/init.pp @@ -77,6 +77,10 @@ class roles { include roles::ftp_upload } + if has_role('ssh.upload.d.o') { + include roles::ssh_upload + } + if has_role('git_master') { include roles::git_master } diff --git a/modules/roles/manifests/ssh_upload.pp b/modules/roles/manifests/ssh_upload.pp new file mode 100644 index 00000000..07a6eb85 --- /dev/null +++ b/modules/roles/manifests/ssh_upload.pp @@ -0,0 +1,10 @@ +class roles::ssh_upload { + file { '/etc/ssh/userkeys/buildd-uploader': + content => template('roles/ssh_upload_buildd-uploader-authorized_keys.erb'), + } + + file { '/home/buildd-uploader/rsync-ssh-wrap': + source => 'puppet:///modules/roles/ssh_upload/rsync-ssh-wrap', + mode => '0555', + } +} diff --git a/modules/roles/templates/ssh_upload_buildd-uploader-authorized_keys.erb b/modules/roles/templates/ssh_upload_buildd-uploader-authorized_keys.erb new file mode 100644 index 00000000..8dccbfb4 --- /dev/null +++ b/modules/roles/templates/ssh_upload_buildd-uploader-authorized_keys.erb @@ -0,0 +1,43 @@ +## +## THIS FILE IS UNDER PUPPET CONTROL. DON'T EDIT IT HERE. +## + +<%= +def getbuilddkey(host) + key = nil + begin + facts = YAML.load(File.open("/var/lib/puppet/yaml/facts/#{host}.yaml").read) + return facts.values['buildd_key'] + rescue Exception => e + end + return key +end + +allnodeinfo = scope.lookupvar('site::allnodeinfo') +buildds = [] + +allnodeinfo.keys.sort.each do |node| + next unless scope.lookupvar('site::allnodeinfo')[node]['purpose'] + next unless scope.lookupvar('site::allnodeinfo')[node]['purpose'].include?('buildd') + key = getbuilddkey(node) + buildds << { 'node' => node, 'addr' => allnodeinfo[node]['ipHostNumber'], 'key' => key} +end + +lines = [] +for m in buildds do + lines << '# ' + m['node'] + if m['key'].nil? + lines << "## no key for node" + else + lines << "command=\"/home/buildd-uploader/rsync-ssh-wrap #{m['node'].split('.')[0]}\"," + + 'no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-user-rc,' + + 'from="' + m['addr'].join(',') + '" ' + + m['key'] + end +end + +lines.join("\n") +# vim:set et: +# vim:set sts=4 ts=4: +# vim:set shiftwidth=4: +%>