Skip to content

Commit 4d64878

Browse files
authored
feat: optional Install netbird overlay vpn (#105)
* feat: add optional NetBird VPN installation and configuration * fix: update public IP retrieval methods * checksum v0.80.2 * update checksum in README
1 parent 78515c6 commit 4d64878

File tree

3 files changed

+185
-24
lines changed

3 files changed

+185
-24
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
-----
99

10-
**Version:** v0.80.1
10+
**Version:** v0.80.2
1111

12-
**Last Updated:** 2026-02-28
12+
**Last Updated:** 2026-03-01
1313

1414
**Compatible With:**
1515

@@ -88,12 +88,12 @@ sha256sum du_setup.sh
8888

8989
Compare the output hash to the one below. They must match exactly.
9090

91-
`b3245890c8e7caae585dd0a3eebe50d9972d3923daafcc894e2b16b92a4f9d1d`
91+
`a1d3da935edcc031f7f4ab5587d19aa46d0519704500531c353a52bdd1a7ce0a`
9292

9393
Or echo the hash to check, it should output: `du_setup.sh: OK`
9494

9595
```bash
96-
echo b3245890c8e7caae585dd0a3eebe50d9972d3923daafcc894e2b16b92a4f9d1d du_setup.sh | sha256sum --check
96+
echo a1d3da935edcc031f7f4ab5587d19aa46d0519704500531c353a52bdd1a7ce0a du_setup.sh | sha256sum --check
9797
```
9898

9999
### 3. Run the Script

du_setup.sh

Lines changed: 180 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#!/bin/bash
22

33
# Debian and Ubuntu Server Hardening Interactive Script
4-
# Version: 0.80.1 | 2026-02-28
4+
# Version: 0.80.2 | 2026-03-01
55
# Changelog:
6+
# - v0.80.2: Added an optional install of netbird (https://netbird.io/) as an alternative to tailscale.
67
# - v0.80.1: Added a safety check to trigger the SSH rollback function if user is disconnected during SSH port change, preventing lockout.
78
# Implement a check for a validated ssh key for the sudo user before revoking root access.
89
# Perform changes to sshd config in a low-lexical-order file (10-hardening.conf) to minimize risk of conflicts with existing provider configs.
@@ -102,7 +103,7 @@
102103
set -euo pipefail
103104

104105
# --- Update Configuration ---
105-
CURRENT_VERSION="0.80.1"
106+
CURRENT_VERSION="0.80.2"
106107
SCRIPT_URL="https://raw.githubusercontent.com/buildplan/du_setup/refs/heads/main/du_setup.sh"
107108
CHECKSUM_URL="${SCRIPT_URL}.sha256"
108109

@@ -261,7 +262,7 @@ print_header() {
261262
printf '%s\n' "${CYAN}╔═════════════════════════════════════════════════════════════════╗${NC}"
262263
printf '%s\n' "${CYAN}║ ║${NC}"
263264
printf '%s\n' "${CYAN}║ DEBIAN/UBUNTU SERVER SETUP AND HARDENING SCRIPT ║${NC}"
264-
printf '%s\n' "${CYAN}║ v0.80.1 | 2026-02-28${NC}"
265+
printf '%s\n' "${CYAN}║ v0.80.2 | 2026-03-01${NC}"
265266
printf '%s\n' "${CYAN}║ ║${NC}"
266267
printf '%s\n' "${CYAN}╚═════════════════════════════════════════════════════════════════╝${NC}"
267268
printf '\n'
@@ -1459,14 +1460,16 @@ sysinfo() {
14591460
local ip_addr public_ipv4 public_ipv6
14601461
14611462
# Try to get public IPv4 first
1462-
public_ipv4=$(curl -4 -s -m 2 --connect-timeout 1 https://checkip.amazonaws.com 2>/dev/null || \
1463-
curl -4 -s -m 2 --connect-timeout 1 https://ipconfig.io 2>/dev/null || \
1464-
curl -4 -s -m 2 --connect-timeout 1 https://api.ipify.org 2>/dev/null)
1463+
public_ipv4=$(curl -4 -sf -m 2 --connect-timeout 1 https://ip.wiredalter.com 2>/dev/null || \
1464+
curl -4 -sf -m 2 --connect-timeout 1 https://checkip.amazonaws.com 2>/dev/null || \
1465+
curl -4 -sf -m 2 --connect-timeout 1 https://ipconfig.io 2>/dev/null || \
1466+
curl -4 -sf -m 2 --connect-timeout 1 https://api.ipify.org 2>/dev/null)
14651467
# If no IPv4, try IPv6
14661468
if [ -z "$public_ipv4" ]; then
1467-
public_ipv6=$(curl -6 -s -m 2 --connect-timeout 1 https://ipconfig.io 2>/dev/null || \
1468-
curl -6 -s -m 2 --connect-timeout 1 https://icanhazip.co 2>/dev/null || \
1469-
curl -6 -s -m 2 --connect-timeout 1 https://api64.ipify.org 2>/dev/null)
1469+
public_ipv6=$(curl -6 -sf -m 2 --connect-timeout 1 https://ip.wiredalter.com 2>/dev/null || \
1470+
curl -6 -sf -m 2 --connect-timeout 1 https://ipconfig.io 2>/dev/null || \
1471+
curl -6 -sf -m 2 --connect-timeout 1 https://icanhazip.co 2>/dev/null || \
1472+
curl -6 -sf -m 2 --connect-timeout 1 https://api64.ipify.org 2>/dev/null)
14701473
fi
14711474
# Get local/internal IP as fallback
14721475
for iface in eth0 ens3 enp0s3 enp0s6 wlan0 ens33 eno1; do
@@ -1739,9 +1742,9 @@ alias top10='ps aux --sort=-%mem | head -n 11'
17391742
17401743
# Quick network info.
17411744
# Get public IP with timeouts (3s), fallbacks, and newline formatting
1742-
alias myip='curl -s --connect-timeout 3 ip.me || curl -s --connect-timeout 3 icanhazip.com || curl -s --connect-timeout 3 ifconfig.me; echo'
1743-
alias myip4='curl -4 -s --connect-timeout 3 ip.me || curl -4 -s --connect-timeout 3 icanhazip.com || curl -4 -s --connect-timeout 3 ifconfig.me; echo'
1744-
alias myip6='curl -6 -s --connect-timeout 3 ip.me || curl -6 -s --connect-timeout 3 icanhazip.com || curl -6 -s --connect-timeout 3 ifconfig.me; echo'
1745+
alias myip='curl -sf --connect-timeout 3 ip.me || curl -sf --connect-timeout 3 icanhazip.com || curl -sf --connect-timeout 3 ifconfig.me; echo'
1746+
alias myip4='curl -4 -sf --connect-timeout 3 ip.me || curl -4 -sf --connect-timeout 3 icanhazip.com || curl -4 -sf --connect-timeout 3 ifconfig.me; echo'
1747+
alias myip6='curl -6 -sf --connect-timeout 3 ip.me || curl -6 -sf --connect-timeout 3 icanhazip.com || curl -6 -sf --connect-timeout 3 ifconfig.me; echo'
17451748
# Show local IP address(es), excluding loopback.
17461749
localip() {
17471750
ip -4 addr | awk '/inet/ {print $2}' | cut -d/ -f1 | grep -v '127.0.0.1'
@@ -2892,14 +2895,16 @@ collect_config() {
28922895
LOCAL_IP_V4=""
28932896
fi
28942897
# 2. Get Public IPs with timeouts
2895-
SERVER_IP_V4=$(curl -4 -s --connect-timeout 4 --max-time 5 https://ifconfig.me 2>/dev/null || \
2896-
curl -4 -s --connect-timeout 4 --max-time 5 https://ip.me 2>/dev/null || \
2897-
curl -4 -s --connect-timeout 4 --max-time 5 https://icanhazip.com 2>/dev/null || \
2898+
SERVER_IP_V4=$(curl -4 -sf --connect-timeout 4 --max-time 5 https://ip.me 2>/dev/null || \
2899+
curl -4 -sf --connect-timeout 4 --max-time 5 https://ip.wiredalter.com 2>/dev/null || \
2900+
curl -4 -sf --connect-timeout 4 --max-time 5 https://ifconfig.me 2>/dev/null || \
2901+
curl -4 -sf --connect-timeout 4 --max-time 5 https://icanhazip.com 2>/dev/null || \
28982902
echo "Unknown")
28992903

2900-
SERVER_IP_V6=$(curl -6 -s --connect-timeout 4 --max-time 5 https://ifconfig.me 2>/dev/null || \
2901-
curl -6 -s --connect-timeout 4 --max-time 5 https://ip.me 2>/dev/null || \
2902-
curl -6 -s --connect-timeout 4 --max-time 5 https://icanhazip.com 2>/dev/null || \
2904+
SERVER_IP_V6=$(curl -6 -sf --connect-timeout 4 --max-time 5 https://ip.me 2>/dev/null || \
2905+
curl -6 -sf --connect-timeout 4 --max-time 5 https://ip.wiredalter.com 2>/dev/null || \
2906+
curl -6 -sf --connect-timeout 4 --max-time 5 https://ifconfig.me 2>/dev/null || \
2907+
curl -6 -sf --connect-timeout 4 --max-time 5 https://icanhazip.com 2>/dev/null || \
29032908
echo "Not available")
29042909

29052910
# --- Display Summary ---
@@ -3314,6 +3319,11 @@ show_connection_options() {
33143319
TS_IP=$(tailscale ip -4 2>/dev/null)
33153320
fi
33163321

3322+
local NB_IP=""
3323+
if command -v netbird >/dev/null 2>&1 && netbird status 2>/dev/null | grep -q "Connected"; then
3324+
NB_IP=$(ip -4 addr show wt0 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1 | head -1)
3325+
fi
3326+
33173327
printf "\n"
33183328

33193329
# 1. Public IP (Internet)
@@ -3349,6 +3359,12 @@ show_connection_options() {
33493359
if [[ -n "$TS_IP" ]]; then
33503360
printf " %-20s ${CYAN}ssh -p %s %s@%s${NC}\n" "Tailscale (VPN):" "$port" "$USERNAME" "$TS_IP"
33513361
fi
3362+
3363+
# 5. NetBird IP (VPN)
3364+
if [[ -n "$NB_IP" ]]; then
3365+
printf " %-20s ${CYAN}ssh -p %s %s@%s${NC}\n" "NetBird (VPN):" "$port" "$USERNAME" "$NB_IP"
3366+
fi
3367+
33523368
printf "\n"
33533369
}
33543370

@@ -4642,7 +4658,7 @@ install_tailscale() {
46424658

46434659
print_info "Configuring Tailscale connection..."
46444660
printf '%s\n' "${CYAN}Choose Tailscale connection method:${NC}"
4645-
printf ' 1) Standard Tailscale (requires pre-auth key from https://login.tailscale.com/admin)\n'
4661+
printf ' 1) Standard Tailscale (requires pre-auth key from https://login.tailscale.com/admin )\n'
46464662
printf ' 2) Custom Tailscale server (requires server URL and pre-auth key)\n'
46474663
read -rp "$(printf '%s' "${CYAN}Enter choice (1-2) [1]: ${NC}")" TS_CONNECTION
46484664
TS_CONNECTION=${TS_CONNECTION:-1}
@@ -4792,6 +4808,111 @@ install_tailscale() {
47924808
log "Tailscale setup completed."
47934809
}
47944810

4811+
install_netbird() {
4812+
if ! confirm "Install and configure NetBird VPN (Optional)?"; then
4813+
print_info "Skipping NetBird installation."
4814+
log "NetBird installation skipped by user."
4815+
return 0
4816+
fi
4817+
print_section "NetBird VPN Installation and Configuration"
4818+
4819+
# Check if NetBird is already installed
4820+
if command -v netbird >/dev/null 2>&1; then
4821+
if systemctl is-active --quiet netbird && netbird status 2>/dev/null | grep -q "Connected"; then
4822+
local NB_IPV4
4823+
NB_IPV4=$(ip -4 addr show wt0 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1 | head -1 || echo "Unknown")
4824+
print_success "NetBird is active and connected. Node IPv4: $NB_IPV4"
4825+
echo "$NB_IPV4" > /tmp/netbird_ips.txt
4826+
return 0
4827+
else
4828+
print_warning "NetBird is installed but not active or connected."
4829+
fi
4830+
else
4831+
print_info "Adding NetBird repository and installing package..."
4832+
if ! apt-get update -qq || ! apt-get install -y -qq ca-certificates curl gnupg; then
4833+
print_error "Failed to install dependencies for NetBird."
4834+
return 1
4835+
fi
4836+
4837+
curl -sSL https://pkgs.netbird.io/debian/public.key | gpg --dearmor --output /usr/share/keyrings/netbird-archive-keyring.gpg 2>/dev/null
4838+
echo 'deb [signed-by=/usr/share/keyrings/netbird-archive-keyring.gpg] https://pkgs.netbird.io/debian stable main' | tee /etc/apt/sources.list.d/netbird.list >/dev/null
4839+
4840+
if ! apt-get update -qq || ! apt-get install -y -qq netbird; then
4841+
print_error "Failed to install NetBird package."
4842+
log "NetBird installation failed."
4843+
return 1
4844+
fi
4845+
print_success "NetBird installation complete."
4846+
log "NetBird installation completed."
4847+
fi
4848+
4849+
if ! confirm "Configure NetBird now?"; then
4850+
print_info "You can configure NetBird later by running: sudo netbird up"
4851+
return 0
4852+
fi
4853+
4854+
print_info "Configuring NetBird connection..."
4855+
printf '%s\n' "${CYAN}Choose NetBird connection method:${NC}"
4856+
printf ' 1) Standard NetBird Cloud (requires setup key from https://app.netbird.io/setup-keys )\n'
4857+
printf ' 2) Custom/Self-hosted NetBird server (requires server URL and setup key)\n'
4858+
4859+
local NB_CONNECTION
4860+
read -rp "$(printf '%s' "${CYAN}Enter choice (1-2) [1]: ${NC}")" NB_CONNECTION
4861+
NB_CONNECTION=${NB_CONNECTION:-1}
4862+
4863+
local SETUP_KEY MANAGEMENT_URL=""
4864+
if [[ "$NB_CONNECTION" == "2" ]]; then
4865+
while true; do
4866+
read -rp "$(printf '%s' "${CYAN}Enter NetBird management URL (e.g., https://netbird.mydomain.com:33073): ${NC}")" MANAGEMENT_URL
4867+
if [[ "$MANAGEMENT_URL" =~ ^https?://[a-zA-Z0-9.-]+(:[0-9]+)?$ ]]; then break; else print_error "Invalid URL. Try again."; fi
4868+
done
4869+
fi
4870+
4871+
while true; do
4872+
read -rsp "$(printf '%s' "${CYAN}Enter NetBird setup key: ${NC}")" SETUP_KEY
4873+
printf '\n'
4874+
if [[ -n "$SETUP_KEY" ]]; then break; else print_error "Setup key cannot be empty."; fi
4875+
done
4876+
4877+
local NB_COMMAND="netbird up --setup-key $SETUP_KEY"
4878+
if [[ "$NB_CONNECTION" == "2" ]]; then
4879+
NB_COMMAND="$NB_COMMAND --management-url $MANAGEMENT_URL"
4880+
fi
4881+
4882+
local NB_COMMAND_SAFE
4883+
NB_COMMAND_SAFE=$(echo "$NB_COMMAND" | sed -E 's/--setup-key [^[:space:]]+/--setup-key REDACTED/g')
4884+
print_info "Connecting to NetBird with: $NB_COMMAND_SAFE"
4885+
4886+
if ! $NB_COMMAND; then
4887+
print_warning "Failed to connect to NetBird. Check setup key or network."
4888+
log "NetBird connection failed: $NB_COMMAND_SAFE"
4889+
else
4890+
# Verify connection
4891+
local RETRIES=3 DELAY=5 CONNECTED=false NB_IPV4=""
4892+
for ((i=1; i<=RETRIES; i++)); do
4893+
if netbird status 2>/dev/null | grep -q "Connected"; then
4894+
NB_IPV4=$(ip -4 addr show wt0 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1 | head -1 || echo "Unknown")
4895+
if [[ -n "$NB_IPV4" && "$NB_IPV4" != "Unknown" ]]; then
4896+
CONNECTED=true
4897+
break
4898+
fi
4899+
fi
4900+
print_info "Waiting for NetBird to connect ($i/$RETRIES)..."
4901+
sleep $DELAY
4902+
done
4903+
4904+
if $CONNECTED; then
4905+
print_success "NetBird connected successfully. Node IPv4 in VPN: $NB_IPV4"
4906+
log "NetBird connected: $NB_COMMAND_SAFE"
4907+
echo "${MANAGEMENT_URL:-https://api.netbird.io}" > /tmp/netbird_server
4908+
echo "$NB_IPV4" > /tmp/netbird_ips.txt
4909+
else
4910+
print_warning "NetBird connection attempt finished, but could not verify IP."
4911+
log "NetBird connection not verified: $NB_COMMAND_SAFE"
4912+
fi
4913+
fi
4914+
}
4915+
47954916
setup_backup() {
47964917
print_section "Backup Configuration (rsync over SSH)"
47974918

@@ -5656,6 +5777,13 @@ generate_summary() {
56565777
fi
56575778
fi
56585779
fi
5780+
if command -v netbird >/dev/null 2>&1; then
5781+
if systemctl is-active --quiet netbird && netbird status 2>/dev/null | grep -q "Connected"; then
5782+
printf " %-20s ${GREEN}✓ Active & Connected${NC}\n" "netbird"
5783+
else
5784+
printf " %-20s ${YELLOW}⚠ Installed but not connected${NC}\n" "netbird"
5785+
fi
5786+
fi
56595787
if [[ "${AUDIT_RAN:-false}" == true ]]; then
56605788
printf " %-20s ${GREEN}✓ Performed${NC}\n" "Security Audit"
56615789
else
@@ -5743,6 +5871,26 @@ generate_summary() {
57435871
printf '%s\n' " Tailscale: ${RED}Not installed${NC}"
57445872
fi
57455873

5874+
# --- NetBird Summary ---
5875+
if command -v netbird >/dev/null 2>&1; then
5876+
local NB_CONFIGURED=false
5877+
if [[ -f /tmp/netbird_ips.txt ]] && grep -qE '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' /tmp/netbird_ips.txt 2>/dev/null; then
5878+
NB_CONFIGURED=true
5879+
fi
5880+
if $NB_CONFIGURED; then
5881+
local NB_SERVER NB_IPS
5882+
NB_SERVER=$(cat /tmp/netbird_server 2>/dev/null || echo "https://api.netbird.io")
5883+
NB_IPS=$(cat /tmp/netbird_ips.txt 2>/dev/null || echo "Not connected")
5884+
printf '%s\n' " NetBird: ${GREEN}Configured and connected${NC}"
5885+
printf " %-17s%s\n" "- Server:" "${NB_SERVER}"
5886+
printf " %-17s%s\n" "- NetBird IPv4:" "${NB_IPS}"
5887+
else
5888+
printf '%s\n' " NetBird: ${YELLOW}Installed but not configured${NC}"
5889+
fi
5890+
else
5891+
printf '%s\n' " NetBird: ${RED}Not installed${NC}"
5892+
fi
5893+
57465894
# --- Security Audit Summary ---
57475895
if [[ "${AUDIT_RAN:-false}" == true ]]; then
57485896
printf '%s\n' " Security Audit: ${GREEN}Performed${NC}"
@@ -5819,6 +5967,15 @@ generate_summary() {
58195967
fi
58205968
fi
58215969

5970+
# 3.1. NetBird Access
5971+
if [[ -f /tmp/netbird_ips.txt ]]; then
5972+
local NB_SUMMARY_IP
5973+
NB_SUMMARY_IP=$(head -n 1 /tmp/netbird_ips.txt)
5974+
if [[ -n "$NB_SUMMARY_IP" ]]; then
5975+
printf " %-26s ${CYAN}%s${NC}\n" "- NetBird (VPN):" "ssh -p $SSH_PORT $USERNAME@$NB_SUMMARY_IP"
5976+
fi
5977+
fi
5978+
58225979
# 4. IPv6 Access
58235980
if [[ "${SERVER_IP_V6:-}" != "not available" && "${SERVER_IP_V6:-}" != "Not available" ]]; then
58245981
printf " %-26s ${CYAN}%s${NC}\n" "- IPv6:" "ssh -p $SSH_PORT $USERNAME@$SERVER_IP_V6"
@@ -5842,6 +5999,9 @@ generate_summary() {
58425999
if command -v tailscale >/dev/null 2>&1; then
58436000
printf " %-28s ${CYAN}%s${NC}\n" "- Tailscale status:" "tailscale status"
58446001
fi
6002+
if command -v netbird >/dev/null 2>&1; then
6003+
printf " %-28s ${CYAN}%s${NC}\n" "- NetBird status:" "netbird status"
6004+
fi
58456005
if [[ -f /root/run_backup.sh ]]; then
58466006
printf ' Remote Backup:\n'
58476007
printf " %-23s ${CYAN}%s${NC}\n" "- Test backup:" "sudo /root/run_backup.sh"
@@ -5971,6 +6131,7 @@ main() {
59716131
configure_kernel_hardening
59726132
install_docker
59736133
install_tailscale
6134+
install_netbird
59746135
setup_backup
59756136
configure_swap
59766137
configure_security_audit

du_setup.sh.sha256

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
b3245890c8e7caae585dd0a3eebe50d9972d3923daafcc894e2b16b92a4f9d1d du_setup.sh
1+
a1d3da935edcc031f7f4ab5587d19aa46d0519704500531c353a52bdd1a7ce0a du_setup.sh

0 commit comments

Comments
 (0)