-
Notifications
You must be signed in to change notification settings - Fork 3
/
install_ns-gce.sh
executable file
·297 lines (270 loc) · 9.7 KB
/
install_ns-gce.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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
#!/bin/bash -x
# This script is meant to be an idempotent script (you can run it multiple
# times in a row).
# This script is meant to be run by the root user (via GCP's cloud-init /
# terraform's custom_data) with no ssh key, no USER or HOME variable, and also
# be run by user cunnie, with ssh keys and environment variables set.
# gcloud compute ssh --zone "us-central1-a" "ns-gce" --project "blabbertabber"
# Output is in /var/log/cloud-init-output.log
set -xeu -o pipefail
install_packages() {
sudo apt-get update
export DEBIAN_FRONTEND=noninteractive
sudo apt-get -y upgrade
sudo apt-get remove -y chrony || true
sudo apt-get install -y \
bat \
build-essential \
direnv \
fasd \
fd-find \
git \
git-lfs \
golang \
jq \
lastpass-cli \
neovim \
nginx \
ntpsec \
python3 \
python3-dev \
python3-pip \
ripgrep \
ruby \
socat \
tcpdump \
tree \
unzip \
zsh \
zsh-syntax-highlighting \
}
configure_user_cunnie() {
# on gcloud this userid is already created
if [ ! -f ~cunnie/.zshrc ]; then
sudo chsh -s /usr/bin/zsh cunnie
for GROUP in root adm sudo www-data; do
sudo adduser cunnie $GROUP
done
echo "cunnie ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/99-cunnie
sudo mkdir -p ~cunnie/.ssh
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIWiAzxc4uovfaphO0QVC2w00YmzrogUpjAzvuqaQ9tD [email protected] " | sudo tee -a ~cunnie/.ssh/authorized_keys
ssh-keyscan github.com | sudo tee -a ~cunnie/.ssh/known_hosts
sudo touch ~cunnie/.zshrc
sudo chmod -R go-rwx ~cunnie/.ssh
sudo git clone https://github.com/cunnie/bin.git ~cunnie/bin
sudo mkdir -p ~cunnie/.local/share # fixes `lpass login → Error: No such file or directory: mkdir(/home/cunnie/.local/share/lpass)`
sudo chown -R cunnie:cunnie ~cunnie
fi
}
install_chruby() {
if [ ! -d /usr/local/share/chruby ] ; then
wget -O ruby-install-0.9.3.tar.gz \
https://github.com/postmodern/ruby-install/releases/download/v0.9.3/ruby-install-0.9.3.tar.gz
tar -xzvf ruby-install-0.9.3.tar.gz
cd ruby-install-0.9.3/
sudo make install
wget -O chruby-0.3.9.tar.gz https://github.com/postmodern/chruby/archive/v0.3.9.tar.gz
tar -xzvf chruby-0.3.9.tar.gz
cd chruby-0.3.9/
sudo make install
cat >> $HOME/.zshrc <<EOF
source /usr/local/share/chruby/chruby.sh
source /usr/local/share/chruby/auto.sh
EOF
fi
}
install_zsh_autosuggestions() {
if [ ! -d $HOME/.oh-my-zsh/custom/plugins/zsh-autosuggestions ]; then
git clone https://github.com/zsh-users/zsh-autosuggestions $HOME/.oh-my-zsh/custom/plugins/zsh-autosuggestions
sed -i 's/^plugins=(/&zsh-autosuggestions /' $HOME/.zshrc
fi
}
configure_direnv() {
if ! grep -q "direnv hook zsh" $HOME/.zshrc; then
echo 'eval "$(direnv hook zsh)"' >> $HOME/.zshrc
eval "$(direnv hook bash)"
fi
for envrc in $(find "$HOME/workspace" -maxdepth 2 -name '.envrc' -print); do
pushd $(dirname $envrc)
direnv allow
popd
done
}
configure_zsh() {
if [ ! -d $HOME/.oh-my-zsh ]; then
sudo chsh -s /usr/bin/zsh $USER
echo "" | SHELL=/usr/bin/zsh zsh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
sed -i 's/robbyrussell/agnoster/' $HOME/.zshrc
echo 'eval "$(fasd --init posix-alias zsh-hook)"' >> $HOME/.zshrc
echo 'export EDITOR=nvim' >> $HOME/.zshrc
fi
}
use_pacific_time() {
sudo timedatectl set-timezone America/Los_Angeles
}
rsyslog_ignores_sslip() {
RSYSLOG_CONFIG=/etc/rsyslog.d/10-sslip.io.conf
if [ ! -f $RSYSLOG_CONFIG ]; then
sudo tee -a $RSYSLOG_CONFIG <<EOF
# sslip.io-dns-server is too verbose, consumed 15G in /var/log
# rely only on journalctl henceforth
:programname, isequal, "sslip.io-dns-server" stop
EOF
sudo systemctl restart syslog
fi
}
configure_git() {
# https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases
git config --global user.name "Brian Cunnie"
git config --global user.email [email protected]
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.st status
git config --global color.branch auto
git config --global color.diff auto
git config --global color.status auto
git config --global core.editor nvim
git config --global url."[email protected]:".insteadOf "https://github.com/"
mkdir -p $HOME/workspace # where we typically clone our repos
}
configure_sudo() {
sudo sed -i 's/# %wheel/%wheel/' /etc/sudoers
}
configure_ntp() {
if ! grep -q time1.google.com /etc/ntp.conf; then
cat <<EOF | sudo tee /etc/ntp.conf
# Our upstream timekeepers; thank you Google
server time1.google.com iburst
server time2.google.com iburst
server time3.google.com iburst
server time4.google.com iburst
# "Batten down the hatches!"
# see http://support.ntp.org/bin/view/Support/AccessRestrictions
restrict default limited kod nomodify notrap nopeer
restrict -6 default limited kod nomodify notrap nopeer
restrict 127.0.0.0 mask 255.0.0.0
restrict -6 ::1
EOF
sudo systemctl enable ntpsec
sudo systemctl start ntpsec
fi
}
install_sslip_io_dns() {
if [ ! -x /usr/bin/sslip.io-dns-server ]; then
GOLANG_ARCH=$ARCH
GOLANG_ARCH=${GOLANG_ARCH/aarch64/arm64}
GOLANG_ARCH=${GOLANG_ARCH/x86_64/amd64}
curl -L https://github.com/cunnie/sslip.io/releases/download/3.2.6/sslip.io-dns-server-linux-$GOLANG_ARCH \
-o sslip.io-dns-server
sudo install sslip.io-dns-server /usr/bin
sudo curl -L https://raw.githubusercontent.com/cunnie/deployments/main/terraform/aws/sslip.io-vm/sslip.io.service \
-o /etc/systemd/system/sslip.io-dns.service
sudo systemctl daemon-reload
sudo systemctl enable sslip.io-dns
sudo systemctl start sslip.io-dns
fi
}
install_sslip_io_web() {
# Fix "conflicting server name "_" on 0.0.0.0:80, ignored"
if [ -L /etc/nginx/sites-enabled/default ]; then
sudo rm /etc/nginx/sites-enabled/default
sudo systemctl enable nginx
sudo systemctl start nginx
if [ ! -d ~/workspace/sslip.io ]; then
git clone https://github.com/cunnie/sslip.io.git ~/workspace/sslip.io
fi
fi
HTML_DIR=/var/nginx/sslip.io
if [ ! -d $HTML_DIR ]; then
sudo mkdir -p $HTML_DIR
sudo rsync -avH ~/workspace/sslip.io/k8s/document_root_sslip.io/ $HTML_DIR/
sudo chown -R $USER $HTML_DIR
sudo chmod -R g+w $HTML_DIR # so I can write acme certificate information
sudo curl -L https://raw.githubusercontent.com/cunnie/deployments/main/terraform/azure/sslip.io-vm/sslip.io.nginx.conf \
-o /etc/nginx/conf.d/sslip.io.conf
sudo systemctl restart nginx # enable sslip.io HTTP
sudo chmod g+rx /var/log/nginx # so I can look at the logs without running sudo
sudo chown -R www-data:www-data $HTML_DIR
fi
}
delete_adminuser() {
if grep -q ^ubuntu: /etc/passwd; then
sudo deluser --remove-home ubuntu
fi
}
delete_weird_google_users() {
for WEIRDO in bosh vcap evanbrown; do
if grep -q ^$WEIRDO: /etc/passwd; then
sudo deluser --remove-home $WEIRDO
fi
done
}
install_tls() {
TLS_DIR=/etc/pki/nginx
if [ ! -d $TLS_DIR ]; then
HTML_DIR=/var/nginx/sslip.io
sudo chown -R $USER $HTML_DIR
PUBLIC_IPV4=$(dig @ns.sslip.io ip.sslip.io TXT +short -4 | tr -d \")
PUBLIC_IPV6=$(dig @ns.sslip.io ip.sslip.io TXT +short -6 | tr -d \")
PUBLIC_IPV4_DASHES=${PUBLIC_IPV4//./-}
PUBLIC_IPV6_DASHES=${PUBLIC_IPV6//:/-}
curl https://get.acme.sh | sh -s [email protected]
~/.acme.sh/acme.sh \
--issue \
-d $PUBLIC_IPV4.sslip.io \
-d $PUBLIC_IPV4_DASHES.sslip.io \
-d $PUBLIC_IPV6_DASHES.sslip.io \
--server https://acme-v02.api.letsencrypt.org/directory \
--keylength ec-256 \
--log \
-w /var/nginx/sslip.io || true # it'll fail & exit if the cert's already issued, but we don't want to exit
sudo mkdir -p $TLS_DIR
sudo chown -R $USER $TLS_DIR
mkdir -p $TLS_DIR/private/
touch $TLS_DIR/server.crt $TLS_DIR/private/server.key
chmod -R g+w $TLS_DIR
chmod -R o-rwx $TLS_DIR/private
sudo chown -R $USER $HTML_DIR
~/.acme.sh/acme.sh \
--install-cert \
-d $PUBLIC_IPV4.sslip.io \
-d $PUBLIC_IPV4_DASHES.sslip.io \
-d $PUBLIC_IPV6_DASHES.sslip.io \
--ecc \
--key-file $TLS_DIR/private/server.key \
--fullchain-file $TLS_DIR/server.crt \
--server https://acme-v02.api.letsencrypt.org/directory \
--reloadcmd "sudo systemctl restart nginx" \
--log
sudo chown -R www-data:www-data $TLS_DIR $HTML_DIR
# Now that we have a cert we can safely load nginx's HTTPS configuration
sudo curl -L https://raw.githubusercontent.com/cunnie/deployments/main/terraform/azure/sslip.io-vm/sslip.io-https.nginx.conf \
-o /etc/nginx/conf.d/sslip.io-https.conf
sudo systemctl restart nginx # enable sslip.io HTTPS
fi
}
id # Who am I? for debugging purposes
START_TIME=$(date +%s)
ARCH=$(uname -m) # `uname -i` returns "unknown" on GCP
export HOSTNAME=$(hostname)
install_packages
configure_sudo
configure_user_cunnie
use_pacific_time
rsyslog_ignores_sslip
if id -u cunnie && [ $(id -u) == $(id -u cunnie) ]; then
configure_git
mkdir -p $HOME/workspace # sometimes run as root via terraform user_data, no HOME
configure_zsh # needs to come before install steps that modify .zshrc
install_chruby
install_zsh_autosuggestions
configure_direnv
configure_ntp
install_sslip_io_dns
install_sslip_io_web # installs HTTP only
# don't bother with TLS, "Invalid identifiers requested :: Cannot issue for \"2600-1900-4000-4d12--.sslip.io\": Domain name contains an invalid character"
# install_tls # gets certs & updates nginx to include HTTPS
delete_adminuser # AMI includes an ubuntu user; delete it
delete_weird_google_users
fi
echo "It took $(( $(date +%s) - START_TIME )) seconds to run"