-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon.sh
198 lines (168 loc) · 6.49 KB
/
common.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#! /bin/bash
#
# common.sh
#
# Common provisioning operations for Burbank Paranormal Research
# Ubuntu machines (currently Ubuntu 22.04 LTS)
#
# Expects the following environment variables to be set:
#
# PROVISION_USER (the new non-root admin user account to add)
# PROVISION_PASSWORD (the new non-root admin user password: needed for "sudo")
# PROVISION_GROUP (the new group for the non-root admin user account)
# PROVISION_PUBLIC_KEY (the SSH public key for the new non-root admin user account)
#
# NOTE: superuser commands still use "sudo" so this script can be run under a
# non-root account even after initial provisioning
#
# NOTE: this script will lock down the root account, disable password-based
# authentication, and it will also remove the root public key; the only way to
# access the root account will be when you are already SSH-ed into the machine
#
# sudo chmod +x ./common.sh
# Non-success exit code: missing environment variable(s)
E_MISSING_ENV=1
# Outputs an error line to STDOUT
#
# Ex: error_line "Missing environment variable"
error_line() {
echo "[ERROR] $1"
}
# Outputs a line to STDOUT
#
# Ex: output_line "Installing common packages..."
output_line() {
echo "[PROVISION] $1"
}
# Provisions a new admin account
#
# Ex: add_admin_account user password group user-public-key
add_admin_account() {
# local variables for readability
local new_user="$1"
local new_password="$2"
local new_group="$3"
local new_public_key="$4"
# add the group first
sudo addgroup $new_group
# create the user non-interactively (no prompt for GECOS information), add
# to the new group, and disable password-based auth
# https://askubuntu.com/a/94067
sudo adduser --gecos "" --disabled-password --ingroup $new_group $new_user
# add the new user to the sudoers group
# https://askubuntu.com/a/168289
sudo usermod -a -G sudo $new_user
# set the password for the new user so "sudo" can be used with a PW
echo "$new_user:$new_password" | sudo chpasswd
# add the SSH data
local new_home_dir="/home/$new_user"
local ssh_dir="$new_home_dir/.ssh"
sudo mkdir -p $ssh_dir
# add the necessary public key for this user
local authorized_keys_file="$ssh_dir/authorized_keys"
sudo touch $authorized_keys_file
sudo echo "$new_public_key" >> $authorized_keys_file
# change the ownership of everything in the new home directory to the new user/group
sudo chown -hR $new_user:$new_group $new_home_dir
# update the permissions on the directories and file(s)
sudo chmod 755 $new_home_dir
sudo chmod 700 $ssh_dir
sudo chmod 600 $authorized_keys_file
}
# Locks down a user account. This removes the public key from the specified account,
# removes its local password, then subsequently locks it.
#
# Ex: lock_down_account user public-key-to-remove
lock_down_account() {
# figure out the home directory depending on the account
local home_dir="/home/$1"
if [ "$1" == "root" ]; then
home_dir="/root"
fi
# remove the public key from the authorized_keys file since we do not want to
# allow the non-root admin account and the root account to share the same key
local authorized_keys_file="$home_dir/.ssh/authorized_keys"
sudo sed -i "/$2/d" $authorized_keys_file
# remove the password from the account and lock it to prevent authentication
# with a local password
# https://askubuntu.com/a/104140
sudo passwd -dl $1
}
# Locks down SSH. This disables direct root login and disables password-based
# authentication entirely.
#
# Ex: lock_down_ssh
lock_down_ssh() {
# disable root login over SSH
local sshd_config_file="/etc/ssh/sshd_config"
sudo perl -p -i -e "s/PermitRootLogin yes/PermitRootLogin no/g" $sshd_config_file
# disable password-based login over SSH
sudo perl -p -i -e "s/PasswordAuthentication yes/PasswordAuthentication no/g" $sshd_config_file
# reload the sshd configuration via systemctl so the changes take effect
output_line "Reloading sshd service configuration..."
sudo systemctl reload sshd
output_line "Reloaded sshd service configuration"
}
# Check our environment variables first before proceeding
HAS_ERROR=0
if [ -z $PROVISION_USER ]; then
error_line "Environment variable PROVISION_USER is not set"
HAS_ERROR=1
fi
if [ -z $PROVISION_PASSWORD ]; then
error_line "Environment variable PROVISION_PASSWORD is not set"
HAS_ERROR=1
fi
if [ -z $PROVISION_GROUP ]; then
error_line "Environment variable PROVISION_GROUP is not set"
HAS_ERROR=1
fi
if [ -z $PROVISION_PUBLIC_KEY ]; then
error_line "Environment variable PROVISION_PUBLIC_KEY is not set"
HAS_ERROR=1
fi
# If any errors occurred, exit with a non-zero status
if [ $HAS_ERROR -eq 1 ]; then
error_line "Exiting with error status $E_MISSING_ENV"
exit $E_MISSING_ENV
fi
output_line "Beginning common machine provisioning..."
# Update the package list(s)
output_line "Updating package list(s)..."
sudo apt-get -y update
output_line "Finished updating package list(s)"
# Upgrade any packages
output_line "Upgrading package(s) if necessary..."
sudo apt-get -y upgrade
output_line "Finished upgrading package(s)"
# Install common development tools (git, gcc, make, etc)
# https://askubuntu.com/a/24198
output_line "Installing common development tools..."
sudo apt-get -y install build-essential
output_line "Finished installing common development tools"
# Install OpenSSH tools
output_line "Installing OpenSSH tools..."
sudo apt-get -y install openssh-client openssh-server
output_line "Finished installing OpenSSH tools"
# Install miscellaneous packages
#
# wget: simple file retrieval tool
# libssl-dev: OpenSSL development libraries
# net-tools: networking tools for debugging/analysis
# zip: compression and decompression support for ZIP files
output_line "Installing miscellaneous packages..."
sudo apt-get -y install wget libssl-dev net-tools zip
output_line "Finished installing miscellaneous packages"
# Add a new non-root admin account
output_line "Adding non-root admin account ($PROVISION_USER)..."
add_admin_account $PROVISION_USER $PROVISION_PASSWORD $PROVISION_GROUP $PROVISION_PUBLIC_KEY
output_line "Finished adding non-root admin account ($PROVISION_USER)"
# Lock down the root account
output_line "Locking down root account..."
lock_down_account root $PROVISION_PUBLIC_KEY
output_line "Finished locking down root account"
# Lock down SSH
output_line "Locking down SSH..."
lock_down_ssh
output_line "Finished locking down SSH"
output_line "Finished common machine provisioning"