-
Notifications
You must be signed in to change notification settings - Fork 13
/
virtual_install.sh
executable file
·234 lines (192 loc) · 7.89 KB
/
virtual_install.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
#!/bin/bash
# this can be run like:
# bash -c "$(curl -fsSL https://raw.github.com/spr-networks/super/master/virtual_install.sh)"
# run with SKIP_VPN=1 to skip vpn peer setup
# run with SKIP_DNS_BLOCK=1 to disable dns block, default is hosts,ads
# add custom blocks with DNS_BLOCK=hosts,ads,facebook
# if configs are already setup it'll only show the login info
# for a clean reset:
# docker compose -f docker-compose-virt.yml down && rm -rf configs && ./virtual_install.sh
if [ $UID -ne 0 ]; then
echo "[-] run as root or with sudo"
exit
fi
install_deps() {
# install upstream docker
apt-get update
apt-get -y install ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor --yes -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt-get -y install --no-install-recommends docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
apt install -y curl git jq qrencode iproute2 wireguard-tools
git clone https://github.com/spr-networks/super.git
cd super
# overwrite docker compose.yml
cp docker-compose-virt.yml docker-compose.yml
}
# if not git dir is available
if [ ! -f "./docker-compose-virt.yml" ]; then
install_deps
fi
docker compose 2>/dev/null >/dev/null
HAS_NEWDC=$?
if [ $HAS_NEWDC -ne 0 ]; then
echo "[-] A newer version of docker is required"
exit 1
fi
# generate default configs
if [ ! -f configs/base/config.sh ]; then
echo "[+] generating configs..."
cp -R base/template_configs/ configs/
mv configs/base/virtual-config.sh configs/base/config.sh
# generate dhcp config
./configs/scripts/gen_coredhcp_yaml.sh > configs/dhcp/coredhcp.yml
touch configs/base/.setup_done
fi
CONTAINER_CHECK=superapi
# pull and start containers
docker inspect "$CONTAINER_CHECK" > /dev/null 2>&1
if [ $? -eq 1 ]; then
echo "[+] starting spr..."
docker compose -f docker-compose-virt.yml pull
docker compose -f docker-compose-virt.yml up -d
else
echo "[+] spr already running"
fi
# external ip
DEV=eth0
DEV=$(ip route get 1.1.1.1 | grep -oP 'dev \K\w+' -m1)
# NOTE if this is not eth0 - change config.sh
# verify its a public ip address
EXTERNAL_IP=$(ip addr show dev $DEV | grep -oP "inet \K[0-9\.]+" -m1)
EXTERNAL_IP=$(echo "$EXTERNAL_IP" | grep -P '^(?!^0\.)(?!^10\.)(?!^100\.6[4-9]\.)(?!^100\.[7-9]\d\.)(?!^100\.1[0-1]\d\.)(?!^100\.12[0-7]\.)(?!^127\.)(?!^169\.254\.)(?!^172\.1[6-9]\.)(?!^172\.2[0-9]\.)(?!^172\.3[0-1]\.)(?!^192\.0\.0\.)(?!^192\.0\.2\.)(?!^192\.88\.99\.)(?!^192\.168\.)(?!^198\.1[8-9]\.)(?!^198\.51\.100\.)(?!^203.0\.113\.)(?!^22[4-9]\.)(?!^23[0-9]\.)(?!^24[0-9]\.)(?!^25[0-5]\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))$')
EXTERNAL_PORT=8000
if [ ${#EXTERNAL_IP} -eq 0 ]; then
echo "[-] failed to get external ip for $DEV"
echo -n "[?] fetch from https://ifconfig.me? [Y/n] "
read YN
if [ "$YN" == "n" ] || [ "$YN" == "N" ] ; then
EXTERNAL_IP="127.0.0.1"
echo "[+] setting endpoint to $EXTERNAL_IP, change this manually in your config"
else
EXTERNAL_IP=$(curl -s "https://ifconfig.me")
fi
fi
# check spr is running
SPR_DIR=$(docker inspect --format='{{index .Config.Labels "com.docker.compose.project.working_dir"}}' "$CONTAINER_CHECK")
if [ ${#SPR_DIR} -eq 0 ]; then
echo "[-] $CONTAINER_CHECK not running"
SPR_DIR=/home/spr/super
exit
fi
# only generate user if init
if [ ! -f $SPR_DIR/configs/auth/auth_users.json ]; then
echo "[+] generating admin password"
PASSWORD=$(cat /dev/urandom | tr -dc '[:alpha:]' | fold -w ${1:-16} | head -n 1)
echo "{\"admin\" : \"$PASSWORD\"}" > $SPR_DIR/configs/auth/auth_users.json
echo "[+] generating token..."
TOKEN=$(dd if=/dev/urandom bs=1 count=32 2>/dev/null | base64)
echo "[{\"Name\": \"admin\", \"Token\": \"$TOKEN\", \"Expire\": 0}]" > $SPR_DIR/configs/auth/auth_tokens.json
else
PASSWORD=$(cat "$SPR_DIR/configs/auth/auth_users.json" | jq -r .admin)
TOKEN=$(cat "$SPR_DIR/configs/auth/auth_tokens.json" | jq -r '.[0].Token')
fi
# dns block. default: hosts,ads
# example, run with: DNS_BLOCK="hosts,malware,facebook,redirect"
if [ -z "$DNS_BLOCK" ]; then
DNS_BLOCK="hosts,ads"
fi
if [ ! -z "$DNS_BLOCK" ] && [ -z $SKIP_DNS_BLOCK ]; then
urls=()
_IFS=$IFS
IFS=','
for f in $DNS_BLOCK; do
if [ "$f" == "hosts" ]; then
urls+=("https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts")
else
urls+=( "https://raw.githubusercontent.com/blocklistproject/Lists/master/${f}.txt" )
fi
done
IFS=$_IFS
CONF='{"BlockLists": [], "PermitDomains": [], "BlockDomains": [], "ClientIPExclusions": null}'
for url in ${urls[@]}; do
CONF=$(echo $CONF | jq ".BlockLists |= . + [{\"URI\": \"$url\", \"Enabled\": true, \"Tags\": []}]")
done
echo $CONF | jq . > $SPR_DIR/state/dns/block_rules.json
fi
echo "[+] login information:"
echo "=========================================================="
HOST=$EXTERNAL_IP
if [ $HOST == "127.0.0.1" ]; then
HOST="sprvirtual"
fi
echo " http tunnel: ssh $HOST -N -L $EXTERNAL_PORT:127.0.0.1:$EXTERNAL_PORT"
echo " url: http://localhost:$EXTERNAL_PORT/"
echo " username: admin"
echo " password: $PASSWORD"
if [ ! -z "$TOKEN" ]; then
echo " token: $TOKEN"
fi
echo "=========================================================="
# if set - exit
if [ ! -z $SKIP_VPN ]; then
exit
fi
sleep 1
while grep "= privkey" $SPR_DIR/configs/wireguard/wg0.conf > /dev/null;
do
echo "... Waiting for wireguard service to start and initialize"
sleep 5
done
# set External IP for SPR for later, so users do not present
# with the internal endpoint IP.
curl 'http://localhost:8000/plugins/wireguard/endpoints' -X 'PUT' -H "Authorization: Bearer ${TOKEN}" --data-raw "[\"${EXTERNAL_IP}\"]"
#only show confirm if its the first one
NUM_PEERS=$(grep '^\[Peer\]' $SPR_DIR/configs/wireguard/wg0.conf 2>/dev/null | wc -l)
echo "[+] num peers already configured: $NUM_PEERS"
# Use the API to generate a wireguard peer
RET=$(curl -s -H "Authorization: Bearer ${TOKEN}" -X PUT http://localhost:8000/plugins/wireguard/peer --data '{}')
PRIVATE_KEY=$(echo $RET | jq -r .Interface.PrivateKey)
PUBLIC_KEY=$(echo $PRIVATE_KEY | wg pubkey)
PUBLIC_KEY_ESCAPED=$(echo \"${PUBLIC_KEY}\" | jq -r @uri)
CLIENT_IP=$(echo $RET | jq -r .Interface.Address)
SERVER_PUBLIC_KEY=$(echo $RET | jq -r .Peer.PublicKey)
PRESHARED_KEY=$(echo $RET | jq -r .Peer.PresharedKey)
DNS_IP=$(echo $RET | jq -r .Interface.DNS)
# Update the Groups for the Device and Name
RET=$(curl -s -H "Authorization: Bearer ${TOKEN}" -X PUT http://localhost:8000/device?identity=${PUBLIC_KEY_ESCAPED} --data "{\"Policies\": [\"wan\", \"dns\"], \"Name\": \"peer${NUM_PEERS}\"}")
# wg client config
_IFS=$IFS
IFS='\n'
CONF=$(cat << EOF
[Interface]
PrivateKey = $PRIVATE_KEY
Address = $CLIENT_IP
DNS = 192.168.2.1
[Peer]
PublicKey = $SERVER_PUBLIC_KEY
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = $EXTERNAL_IP:51280
PersistentKeepalive = 25
PresharedKey = $PRESHARED_KEY
EOF
)
IFS=$_IFS
echo -e "\n[+] WireGuard config (save this as wg.conf & import in client):\n"
echo -e "$CONF\n"
>/dev/tty printf "Show QR Code? [Y/n] "
</dev/tty read -rn1
if [[ ! $REPLY =~ [nN](oO)* ]]; then
echo -e "[+] WireGuard QR Code (import in iOS & Android app):\n"
echo -e "$CONF" | qrencode -t ansiutf8
fi
# reload dns if we have modified blocks
if [ ! -z "$DNS_BLOCK" ]; then
docker compose -f docker-compose-virt.yml restart dns >/dev/null 2>&1 &
fi