blob: 0446032ed1fa5a7f80898a217f3d2fec9fcb1379 (
plain) (
blame)
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
|
#!/bin/bash
set -euo pipefail
abort() {
printf "\033[31m%s\033[0m\n" "$@" >&2
exit 1
}
log() {
printf "%s\n" "$@"
}
ensure_visudo() {
if ! command -v visudo >/dev/null 2>&1; then
log "visudo was not found"
log "Please install visudo for your distro"
abort "sudo must be installed"
fi
}
ensure_curl() {
if ! command -v curl >/dev/null 2>&1; then
log "curl was not found"
log "Please install curl for your distro"
abort "curl must be installed"
fi
}
ensure_acl() {
if ! command -v setfacl >/dev/null 2>&1; then
log "ACL tools not found"
log "Please install acl for your distro"
abort "setfacl must be installed"
fi
}
ensure_wg() {
if ! command -v wg >/dev/null 2>&1; then
log "Wireguard tools not found"
log "Please install wireguard for your distro"
abort "wg/wg-quick must be installed"
fi
WIREGUARD_PATH="$(which wg)"
WIREGUARD_QUICK_PATH="$(which wg-quick)"
}
ensure_systemd() {
if ! systemctl --version >/dev/null 2>&1; then
abort "systemd is required but not available"
fi
}
ensure_sudo() {
if [ "$EUID" -ne 0 ]; then
abort "Must be run as sudo"
fi
}
get_arch() {
ARCH=$(uname -m)
case $ARCH in
x86_64) ARCH="amd64" ;;
aarch64) ARCH="arm64" ;;
armv7l) ARCH="arm" ;;
*) abort "Unsupported architecture: $ARCH" ;;
esac
log "Architecture: $ARCH"
}
get_version() {
if [ "$VERSION" = "latest" ]; then
RELEASE_URL="https://api.github.com/repos/a14m/wg-portal/releases/latest"
VERSION=$(curl -s "$RELEASE_URL" | grep '"tag_name":' | cut -d '"' -f 4)
log "Latest version: $VERSION"
fi
}
validate_version() {
if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] && [ "$VERSION" != "latest" ]; then
abort "Invalid version format: $VERSION (valid format example v1.0.0)"
fi
}
create_tmp() {
TMP_DIR=$(mktemp -d)
trap 'rm -rf $TMP_DIR' EXIT
}
download_binary() {
log "Downloading wg-portal binary"
DOWNLOAD_URL="https://github.com/a14m/wg-portal/releases/download/$VERSION/wg-portal-linux-${ARCH}"
if ! timeout 120 curl -s -L -o "$TMP_DIR/wg-portal" "$DOWNLOAD_URL"; then
log "Failed to download $DOWNLOAD_URL"
abort "Failed to download wg-portal binary"
fi
log "Downloaded $TMP_DIR/wg-portal"
}
download_systemd_service() {
log "Downloading wg-portal.service"
DOWNLOAD_SERVICE_URL="https://git.sr.ht/~a14m/wg-portal/blob/$VERSION/deployment/wg-portal.service"
if ! timeout 30 curl -s -L -o "$TMP_DIR/wg-portal.service" "$DOWNLOAD_SERVICE_URL"; then
log "Failed to download $DOWNLOAD_SERVICE_URL"
abort "Failed to download wg-portal.service"
fi
log "Downloaded $TMP_DIR/wg-portal.service"
}
create_system_user() {
if ! id -u wg-portal >/dev/null 2>&1; then
log "Creating wg-portal system user and group..."
useradd --system --no-create-home --shell /usr/sbin/nologin wg-portal
else
log "User wg-portal already exists"
fi
}
create_etc_directory() {
log "Creating /etc/wg-portal directory..."
mkdir -p /etc/wg-portal
chown root:wg-portal /etc/wg-portal
chmod 750 /etc/wg-portal
}
configure_access_control() {
log "Configure ACL for /etc/wireguard"
setfacl -R -m g:wg-portal:r /etc/wireguard
log "Setting up wg-portal user/group sudo permissions"
cat > "$TMP_DIR/wg-portal-sudoers" << EOF
%wg-portal ALL=(ALL) NOPASSWD: ${WIREGUARD_QUICK_PATH} up *, ${WIREGUARD_QUICK_PATH} down *
%wg-portal ALL=(ALL) NOPASSWD: ${WIREGUARD_PATH} show
EOF
# Validate before installing
if visudo -c -f "$TMP_DIR/wg-portal-sudoers"; then
mv "$TMP_DIR/wg-portal-sudoers" /etc/sudoers.d/wg-portal
chmod 440 /etc/sudoers.d/wg-portal
else
abort "Invalid sudoers configuration"
fi
}
install_binary() {
log "Installing wg-portal binary to /etc/wg-portal"
chmod +x "$TMP_DIR/wg-portal"
mv "$TMP_DIR/wg-portal" /etc/wg-portal
}
install_systemd_service() {
log "Installing wg-portal systemd service..."
mv "$TMP_DIR/wg-portal.service" /etc/systemd/system/wg-portal.service
systemctl daemon-reload
systemctl enable wg-portal
log "Service installed and enabled"
}
show_completion_message() {
log ""
log "wg-portal installed successfully!"
log ""
log "Configuration:"
log " - Configuration file: /etc/wg-portal/config.yml"
log ""
log "Service Information:"
log " - Binary installed: /etc/wg-portal/wg-portal"
log " - Service: wg-portal.service (enabled)"
log " - User: wg-portal (system user)"
log ""
log "Useful Commands:"
log " - Check status: systemctl status wg-portal"
log " - View logs: journalctl -u wg-portal -f"
log " - Restart: systemctl restart wg-portal"
log " - Stop: systemctl stop wg-portal"
log ""
log "Next steps:"
log " - Configure: /etc/wg-portal/config"
log " - Start Service: systemctl start wg-portal"
}
# Configuration
VERSION=${1:-latest}
# Main
ensure_visudo
ensure_curl
ensure_acl
ensure_wg
ensure_systemd
ensure_sudo
get_arch
get_version
validate_version
create_tmp
download_binary
download_systemd_service
create_system_user
create_etc_directory
configure_access_control
install_binary
install_systemd_service
show_completion_message
|