Skip to content

Commit

Permalink
Add bastion role
Browse files Browse the repository at this point in the history
This:

1.  Installs puppet bolt,
2.  Manages the server's /etc/ssh/ssh_known_hosts file based on puppet facts,
3.  Creates an account dedicated to running git pull automatically, and
4.  Allows sshd to run on ports other than 22.
  • Loading branch information
daaang committed Sep 18, 2024
1 parent 1c32413 commit 2e5dd9d
Show file tree
Hide file tree
Showing 13 changed files with 213 additions and 0 deletions.
1 change: 1 addition & 0 deletions .fixtures.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ fixtures:
reboot: {"repo": "puppetlabs/reboot", "ref": "5.0.0" }
sshkeys_core: {"repo": "puppetlabs/sshkeys_core", "ref": "2.5.0" }
stdlib: {"repo": "puppetlabs/stdlib", "ref": "9.6.0" }
vcsrepo: {"repo": "puppetlabs/vcsrepo", "ref": "6.1.0" }
debconf: {"repo": "stm/debconf", "ref": "6.0.0" }
#postgresql: {"repo": "puppetlabs/postgresql", "ref": "8.3.0"}
#puppetdb: {"repo": "puppetlabs/puppetdb", "ref": "7.13.0"}
49 changes: 49 additions & 0 deletions manifests/profile/bolt.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright (c) 2024 The Regents of the University of Michigan.
# All Rights Reserved. Licensed according to the terms of the Revised
# BSD License. See LICENSE.txt for details.

class nebula::profile::bolt {
include nebula::profile::managed_known_hosts
include nebula::profile::github_pull_account
include nebula::virtual::users
package { 'puppet-bolt': }

$users = lookup('nebula::profile::authorized_keys::ssh_keys').keys
$all_users = lookup('nebula::virtual::users::all_users')

$users.each |$user| {
$data = $all_users[$user]

User <| title == $user |> {
home => "/home/${user}",
gid => 100,
require => File["/home/${user}"],
}

file { "/home/${user}":
ensure => 'directory',
owner => $data['uid'],
group => 100,
mode => '0755',
}
}

file { "/opt/bolt":
ensure => "directory",
owner => "git",
group => 100,
mode => "0755",
}

vcsrepo { "/opt/bolt":
provider => "git",
ensure => "latest",
source => "ssh://[email protected]/mlibrary/bolt.git",
user => "git",
require => [
Class["nebula::profile::github_pull_account"],
File["/opt/bolt"],
Package["git"],
]
}
}
50 changes: 50 additions & 0 deletions manifests/profile/github_pull_account.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright (c) 2024 The Regents of the University of Michigan.
# All Rights Reserved. Licensed according to the terms of the Revised
# BSD License. See LICENSE.txt for details.

class nebula::profile::github_pull_account (
String $git_username = "git",
Integer $git_gid = 100,
String $git_homedir = "/var/lib/autogit",
) {
package { "git": }

user { $git_username:
ensure => "present",
home => $git_homedir,
gid => $git_gid,
managehome => true,
}

file { "${git_homedir}/.ssh":
ensure => "directory",
owner => $git_username,
group => $git_gid,
mode => "0700",
require => User[$git_username],
}

# Once this exists, you have to add the id_ecdsa.pub to any private
# github repos you want to pull.
exec { "create ${git_homedir}/.ssh/id_ecdsa":
creates => "${git_homedir}/.ssh/id_ecdsa",
user => $git_username,
command => "/usr/bin/ssh-keygen -t ecdsa -N '' -C '${::hostname}' -f ${git_homedir}/.ssh/id_ecdsa",
require => File["${git_homedir}/.ssh"],
}

exec { "create /var/local/github_ssh_keys":
creates => "/var/local/github_ssh_keys",
command => "/usr/bin/ssh-keyscan github.com > /var/local/github_ssh_keys",
}

include nebula::profile::managed_known_hosts

# Without this, the git user will not be able to pull from private
# repos using ssh.
concat_fragment { "github ssh keys":
target => "/etc/ssh/ssh_known_hosts",
source => "/var/local/github_ssh_keys",
require => Exec["create /var/local/github_ssh_keys"],
}
}
10 changes: 10 additions & 0 deletions manifests/profile/managed_known_hosts.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copyright (c) 2024 The Regents of the University of Michigan.
# All Rights Reserved. Licensed according to the terms of the Revised
# BSD License. See LICENSE.txt for details.

class nebula::profile::managed_known_hosts {
concat { '/etc/ssh/ssh_known_hosts': }

# See nebula::profile::known_host_public_keys
Concat_fragment <<| tag == 'known_host_public_keys' |>>
}
6 changes: 6 additions & 0 deletions manifests/profile/networking/firewall.pp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@
]
}

'fwknop': {
$input_ignore = ['-j FWKNOP_INPUT']
$output_ignore = []
$forward_ignore = []
}

default: {
$input_ignore = []
$output_ignore = []
Expand Down
1 change: 1 addition & 0 deletions manifests/profile/networking/sshd.pp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
class nebula::profile::networking::sshd (
Array[String] $whitelist,
String $addon_directives = '',
Integer $port = 22,
) {

# This will do nothing if the keytab doesn't exist
Expand Down
16 changes: 16 additions & 0 deletions manifests/role/bastion.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright (c) 2022 The Regents of the University of Michigan.
# All Rights Reserved. Licensed according to the terms of the Revised
# BSD License. See LICENSE.txt for details.

class nebula::role::bastion {
include nebula::role::minimum

include nebula::profile::bolt
include nebula::profile::root_ssh_private_keys

# These three are effectively the requirements for getting user login
# with kerberos and duo.
include nebula::profile::duo
include nebula::profile::krb5
include nebula::profile::networking
}
1 change: 1 addition & 0 deletions metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
{"name": "puppetlabs/reboot", "version_requirement": ">= 5.0.0 < 6.0.0" },
{"name": "puppetlabs/sshkeys_core", "version_requirement": ">= 2.5.0 < 3.0.0" },
{"name": "puppetlabs/stdlib", "version_requirement": ">= 9.6.0 < 10.0.0"},
{"name": "puppetlabs/vcsrepo", "version_requirement": ">= 6.1.0 < 7.0.0"},
{"name": "stm/debconf", "version_requirement": ">= 6.0.0 < 7.0.0" }
],
"operatingsystem_support": [
Expand Down
19 changes: 19 additions & 0 deletions spec/classes/profile/bolt_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

# Copyright (c) 2022, 2024 The Regents of the University of Michigan.
# All Rights Reserved. Licensed according to the terms of the Revised
# BSD License. See LICENSE.txt for details.
require 'spec_helper'

describe 'nebula::profile::bolt' do
on_supported_os.each do |os, os_facts|
context "on #{os}" do
let(:facts) { os_facts }

it { is_expected.to compile }
it { is_expected.to contain_package('puppet-bolt') }
it { is_expected.to contain_file('/opt/bolt').with_ensure('directory') }
it { is_expected.to contain_vcsrepo('/opt/bolt').with_ensure('latest') }
end
end
end
24 changes: 24 additions & 0 deletions spec/classes/profile/github_pull_account_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

# Copyright (c) 2024 The Regents of the University of Michigan.
# All Rights Reserved. Licensed according to the terms of the Revised
# BSD License. See LICENSE.txt for details.
require 'spec_helper'

describe 'nebula::profile::github_pull_account' do
on_supported_os.each do |os, os_facts|
context "on #{os}" do
let(:facts) { os_facts }

it { is_expected.to compile }
it { is_expected.to contain_user('git').with_home('/var/lib/autogit') }
it { is_expected.to contain_user('git').with_gid(100) }
it { is_expected.to contain_user('git').with_managehome(true) }
it { is_expected.to contain_file('/var/lib/autogit/.ssh').with_ensure('directory') }
it { is_expected.to contain_file('/var/lib/autogit/.ssh').with_mode('0700') }
it { is_expected.to contain_exec('create /var/lib/autogit/.ssh/id_ecdsa') }
it { is_expected.to contain_exec('create /var/local/github_ssh_keys') }
it { is_expected.to contain_concat_fragment('github ssh keys').with_target('/etc/ssh/ssh_known_hosts') }
end
end
end
17 changes: 17 additions & 0 deletions spec/classes/profile/managed_known_hosts_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

# Copyright (c) 2024 The Regents of the University of Michigan.
# All Rights Reserved. Licensed according to the terms of the Revised
# BSD License. See LICENSE.txt for details.
require 'spec_helper'

describe 'nebula::profile::managed_known_hosts' do
on_supported_os.each do |os, os_facts|
context "on #{os}" do
let(:facts) { os_facts }

it { is_expected.to compile }
it { is_expected.to contain_concat('/etc/ssh/ssh_known_hosts') }
end
end
end
15 changes: 15 additions & 0 deletions spec/classes/profile/networking/sshd_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def contain_sshd
end

[
%r{^#Port 22$},
%r{^PermitRootLogin (prohibit|without)-password$},
%r{^PubkeyAuthentication no$},
%r{^PasswordAuthentication no$},
Expand Down Expand Up @@ -97,6 +98,20 @@ class { 'nebula::profile::networking::keytab':
.with_target('/etc/pam.d/sshd')
.with_content(%r{@include sshd-defaults})
end

context 'with port set to 44' do
let(:params) { { port: 44 } }

it { is_expected.not_to contain_sshd.with_content(%r{^#Port 22$}) }
it { is_expected.to contain_sshd.with_content(%r{^Port 44$}) }
end

context 'with port set to 333' do
let(:params) { { port: 333 } }

it { is_expected.not_to contain_sshd.with_content(%r{^#Port 22$}) }
it { is_expected.to contain_sshd.with_content(%r{^Port 333$}) }
end
end
end
end
4 changes: 4 additions & 0 deletions templates/profile/networking/sshd_config.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
# possible, but leave them commented. Uncommented options override the
# default value.

<% if @port == 22 -%>
#Port 22
<% else -%>
Port <%= @port %>
<% end -%>
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
Expand Down

0 comments on commit 2e5dd9d

Please sign in to comment.