Skip to content

Instantly share code, notes, and snippets.

@acidprime
Last active February 10, 2021 23:53
Show Gist options
  • Save acidprime/1778440802dcc250b9560be55fff5f44 to your computer and use it in GitHub Desktop.
Save acidprime/1778440802dcc250b9560be55fff5f44 to your computer and use it in GitHub Desktop.
Getting GDM to open ssh:// links that resolve to docker containers (or any other ssh link).
.vagrant
.deb

Docker Exec SSH Passhthrough

User Clicks SSH Link

This is an example of setting up a Ubuntu 18.04 and a GDM3 installation to allow test users the ability to click on ssh links to automatically login to docker containers running on the users local system.

Test Environment

I used a vagrant file here for testing, you can use it via the following commands.

Note I tested with vagrant and virtualbox, see your OS's results on installing them.

git clone git@gist.github.com:1778440802dcc250b9560be55fff5f44.git docker_ssh
cd docker_ssh
vagrant up

This box is from the UK, you need to change the region if you want to type special commands like '@' on a US keyboard.

Configuring GDM & Docker

I have included some example scripts that will configure the system via Puppet. The gist of these scripts is that they will configure users that have pass through scripts as shells. These pass through scripts will log them into docker via docker exec. This along with the URL handler allows the user to simply click on the right link to get the right container. It should work with any app that works with the xdg style apis e.g. from the commandline xdg-open ssh://scenario1@localhost. I have included an example HTML file with the links.

  1. Login to the vagrant box (password vagrant)
  2. Open a terminal and type cd /vagrant
  3. As the current user (vagrant) type ./setup.sh
  4. Open the example.html and click on the links.

This will install Puppet and run the configuration (with sudo) as needed for all the global configurations and the per-user configurations.

I kept the provisioning manual here as vagrant is not this examples final home. The puppet code should provide an overview of what resources and connections are needed here e.g. ssh keys for localhost.

Versions tested

Software Version
Ubuntu 18.04
Puppet 6.21.0
Docker 18.0.9
Vagrant 2.2.14
VirtualBox 6.1.16
<html>
<a href="ssh://scenario1@localhost">🖥️ Start Scenario One</a><p>
<a href="ssh://scenario2@localhost">🖥️ Start Scenario Two</a><p>
<a href="ssh://scenario3@localhost">🖥️ Start Scenario Three</a><p>
</html>
#!/bin/bash
bold=$(tput bold)
normal=$(tput sgr0)
echo "${bold}Installing Puppet...${normal}"
if [ ! -f /opt/puppetlabs/puppet/bin/puppet ] ; then
wget https://apt.puppetlabs.com/puppet6-release-bionic.deb
sudo dpkg -i puppet6-release-bionic.deb && rm puppet6-release-bionic.deb
sudo apt update
sudo apt-get install puppet-agent
fi
echo "${bold}Installing Puppet Modules...${normal}"
sudo /opt/puppetlabs/puppet/bin/puppet module install puppetlabs-docker --version 3.13.1
sudo /opt/puppetlabs/puppet/bin/puppet module install puppet-ssh_keygen --version 4.1.0
sudo /opt/puppetlabs/puppet/bin/puppet module install herculesteam-augeasproviders_ssh --version 4.0.0
echo "${bold}Configuring Users with Puppet...${normal}"
sudo ./users.pp
echo "${bold}Configuring SSH URL handler as ${USER}...${normal}"
sudo ./ssh.pp
#Check which handler is setup for SSH
xdg-mime query default x-scheme-handler/ssh
#Write code for new handler
cat << EOF > ~/.local/share/applications/ssh.desktop
[Desktop Entry]
Version=1.0
Name=SSH Launcher
Exec=bash -c '(URL="%U" ; ssh "\${URL##ssh://}"); bash'
Terminal=true
Type=Application
Icon=utilities-terminal
EOF
#Apply New handler for SSH
xdg-mime default ssh.desktop x-scheme-handler/ssh
#Confirm new handler has been applied
xdg-mime query default x-scheme-handler/ssh
#!/opt/puppetlabs/puppet/bin/puppet apply
# Configure SSH automation
# This means we technically could start the containers on demand, or stop them
# at time of provisioning and start them at first login to save CPU.
service {'sshd':
ensure => 'running',
}
# Central Authorized Key
ssh_authorized_key { "vagrant@localhost":
ensure => present,
user => root,
type => split(file('/home/vagrant/.ssh/id_rsa.pub'),' ')[0],
key => split(file('/home/vagrant/.ssh/id_rsa.pub'),' ')[1],
target => '/etc/authorized_keys'
}
file {"/usr/local/bin/authorized_key_command":
ensure => file,
owner => root,
mode => '0755',
content => @("SHELL"/L)
#!/bin/bash
[ $# -ne 1 ] && { echo "Usage: $0 userid" >&2; exit 1; }
/usr/bin/docker start $1 &>/dev/null
cat /etc/authorized_keys
| SHELL
} ->
sshd_config { 'AuthorizedKeysCommand':
ensure => 'present',
provider => 'augeas',
value => ['/usr/local/bin/authorized_key_command'],
notify => Service['sshd'],
} ->
sshd_config { 'AuthorizedKeysCommandUser':
ensure => 'present',
provider => 'augeas',
value => ['root'],
notify => Service['sshd'],
}
#!/opt/puppetlabs/puppet/bin/puppet apply
# Setup the SSH key (private)
ssh_keygen { 'vagrant':
type => 'rsa',
bits => 2048,
comment => "Console User",
}
# This vagrant box doesn't have a clean apt config
Exec <| title == 'apt_update' |> {
returns => [0,100]
}
# Install docker (pre-installed in vagrant box, thus we don't manage)
class {'docker':
manage_package => false,
}
# Download the docker image (same as host version)
docker::image { 'ubuntu':
image_tag => 'bionic',
require => Class['docker'],
}
# Loop through the number of users you want to create.
$scenarios = [1,2,3]
each($scenarios) |$n| {
# Setup the users custom shell as pass through to docker
file {"/usr/local/bin/scenario${n}.sh":
ensure => file,
owner => root,
mode => '0755',
content => @("SHELL"/L)
#!/bin/bash
/usr/bin/docker exec -it scenario${n} bash
| SHELL
} ->
# Create the user
user {"scenario${n}":
ensure => 'present',
managehome => true,
groups => ['docker'],
purge_ssh_keys => false,
shell => "/usr/local/bin/scenario${n}.sh",
}
# Run the container for good measure (could stop here too)
docker::run { "scenario${n}":
image => 'ubuntu',
hostname => "scenario${n}",
command => 'tail -f /dev/null',
require => Docker::Image['ubuntu'],
}
}
Vagrant.configure("2") do |config|
config.vm.box = "briancoit/ubuntu18-dev-vm"
config.vm.box_version = "1.0.0"
config.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
vb.gui = true
vb.memory = '2048'
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment