-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeploy.sh
More file actions
executable file
·206 lines (178 loc) · 5.76 KB
/
Copy pathdeploy.sh
File metadata and controls
executable file
·206 lines (178 loc) · 5.76 KB
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
#!/usr/bin/env bash
set -Eeuo pipefail
# Deploy a SIM800C PPP connection and an ngrok SSH tunnel in an isolated netns.
# Run as: sudo NGROK_AUTHTOKEN='...' ./deploy.sh
NETNS="${NETNS:-gprs}"
SERIAL_DEVICE="${SERIAL_DEVICE:-/dev/serial0}"
APN="${APN:-internet}"
NGROK_REGION="${NGROK_REGION:-}"
HOST_ADDR="169.254.200.1/30"
NS_ADDR="169.254.200.2/30"
[[ ${EUID} -eq 0 ]] || { echo "Run this script as root (sudo)." >&2; exit 1; }
[[ -n ${NGROK_AUTHTOKEN:-} ]] || {
echo "NGROK_AUTHTOKEN must be supplied in the environment." >&2
echo "Example: sudo NGROK_AUTHTOKEN='token' ./deploy.sh" >&2
exit 1
}
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y --no-install-recommends ca-certificates curl iproute2 iputils-ping ppp openssh-server tar
# The Pi 2 is normally armv7/armhf. Keep detection explicit so failures are safe.
case "$(dpkg --print-architecture)" in
armhf) NGROK_ARCH=arm ;;
arm64) NGROK_ARCH=arm64 ;;
*) echo "Unsupported architecture: $(dpkg --print-architecture)" >&2; exit 1 ;;
esac
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
curl --fail --silent --show-error --location \
"https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-${NGROK_ARCH}.tgz" \
-o "$tmpdir/ngrok.tgz"
tar -xzf "$tmpdir/ngrok.tgz" -C "$tmpdir" ngrok
install -o root -g root -m 0755 "$tmpdir/ngrok" /usr/local/bin/ngrok
# Serial console must not own the HAT UART. Enabling UART is harmless when the
# setting is already present; disabling the console takes effect after reboot.
if command -v raspi-config >/dev/null; then
raspi-config nonint do_serial_cons 1 || true
raspi-config nonint do_serial 0 || true
fi
if ! grep -q '^enable_uart=1' /boot/config.txt 2>/dev/null; then
printf '\nenable_uart=1\n' >>/boot/config.txt
fi
systemctl disable --now serial-getty@serial0.service 2>/dev/null || true
install -d -m 0755 /etc/chatscripts /etc/ppp/peers /etc/ngrok /etc/netns/"$NETNS"
cat >/etc/chatscripts/sim800c <<EOF
ABORT 'BUSY'
ABORT 'NO CARRIER'
ABORT 'ERROR'
TIMEOUT 20
'' AT
OK ATE0
OK AT+CPIN?
OK AT+CGDCONT=1,"IP","${APN}"
OK ATD*99***1#
CONNECT ''
EOF
cat >/etc/ppp/peers/sim800c <<EOF
${SERIAL_DEVICE} 115200
connect "/usr/sbin/chat -v -f /etc/chatscripts/sim800c"
noauth
defaultroute
usepeerdns
persist
holdoff 10
maxfail 0
hide-password
novj
novjccomp
noipdefault
ipcp-accept-local
ipcp-accept-remote
EOF
printf 'nameserver 1.1.1.1\nnameserver 8.8.8.8\n' >"/etc/netns/${NETNS}/resolv.conf"
# Store the supplied secret root-only; never place it in this repository.
umask 077
region_line=""
[[ -n "$NGROK_REGION" ]] && region_line=" region: ${NGROK_REGION}"
cat >/etc/ngrok/ngrok.yml <<EOF
version: "3"
agent:
authtoken: ${NGROK_AUTHTOKEN}
${region_line}
tunnels:
ssh:
proto: tcp
addr: 169.254.200.1:22
EOF
chmod 0600 /etc/ngrok/ngrok.yml
cat >/usr/local/sbin/gprs-netns-up <<EOF
#!/bin/sh
set -eu
ip netns add ${NETNS} 2>/dev/null || true
ip link del gprs-host 2>/dev/null || true
ip link add gprs-host type veth peer name gprs-ns
ip link set gprs-ns netns ${NETNS}
ip addr add ${HOST_ADDR} dev gprs-host
ip link set gprs-host up
ip netns exec ${NETNS} ip addr add ${NS_ADDR} dev gprs-ns
ip netns exec ${NETNS} ip link set lo up
ip netns exec ${NETNS} ip link set gprs-ns up
EOF
chmod 0755 /usr/local/sbin/gprs-netns-up
# Install the autonomous health checker shipped beside this deployment script.
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
[[ -f "$SCRIPT_DIR/connection-manager.sh" ]] || {
echo "Missing $SCRIPT_DIR/connection-manager.sh; extract the complete package." >&2
exit 1
}
install -o root -g root -m 0755 "$SCRIPT_DIR/connection-manager.sh" \
/usr/local/sbin/gprs-connection-manager
cat >/etc/systemd/system/gprs-netns.service <<EOF
[Unit]
Description=Network namespace for SIM800C data
Before=gprs-ppp.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/gprs-netns-up
ExecStop=-/usr/sbin/ip netns delete ${NETNS}
[Install]
WantedBy=multi-user.target
EOF
cat >/etc/systemd/system/gprs-ppp.service <<EOF
[Unit]
Description=SIM800C PPP connection in isolated namespace
Requires=gprs-netns.service
After=gprs-netns.service dev-serial0.device
[Service]
Type=simple
ExecStart=/usr/sbin/ip netns exec ${NETNS} /usr/sbin/pppd nodetach call sim800c
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
cat >/etc/systemd/system/ngrok-gprs.service <<EOF
[Unit]
Description=ngrok SSH tunnel over SIM800C
Requires=gprs-ppp.service
After=gprs-ppp.service
[Service]
Type=simple
ExecStartPre=/bin/sh -c 'until /usr/sbin/ip netns exec ${NETNS} ip link show ppp0 >/dev/null 2>&1; do sleep 2; done'
ExecStart=/usr/sbin/ip netns exec ${NETNS} /usr/local/bin/ngrok start ssh --config /etc/ngrok/ngrok.yml --log stdout
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
cat >/etc/systemd/system/gprs-connection-manager.service <<EOF
[Unit]
Description=Check and recover SIM800C PPP and ngrok
After=gprs-ppp.service ngrok-gprs.service
[Service]
Type=oneshot
Environment=NETNS=${NETNS}
ExecStart=/usr/local/sbin/gprs-connection-manager check
EOF
cat >/etc/systemd/system/gprs-connection-manager.timer <<EOF
[Unit]
Description=Periodically monitor SIM800C PPP and ngrok
[Timer]
OnBootSec=2min
OnUnitActiveSec=1min
RandomizedDelaySec=10
Persistent=true
Unit=gprs-connection-manager.service
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable ssh gprs-netns.service gprs-ppp.service ngrok-gprs.service \
gprs-connection-manager.timer
systemctl restart ssh gprs-netns.service
# Do not block deployment while a modem is registering or UART awaits a reboot.
systemctl restart --no-block gprs-ppp.service ngrok-gprs.service
systemctl restart gprs-connection-manager.timer
echo "Deployment complete. A reboot is recommended if UART settings changed."
echo "Inspect with: systemctl status gprs-ppp ngrok-gprs"