Add initial setup scripts and configuration for Pangolin DigitalOcean Marketplace app

This commit is contained in:
jkpe 2025-04-11 15:39:14 +01:00
commit ae159cfd69
No known key found for this signature in database
12 changed files with 668 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
.DS_Store

183
DEPLOYMENT.md Normal file
View file

@ -0,0 +1,183 @@
# Pangolin Deployment Guide
This guide walks you through deploying and configuring Pangolin using the DigitalOcean Marketplace 1-Click App.
## Deployment Steps
### 1. Create a Droplet from the Marketplace
1. Log in to your [DigitalOcean account](https://cloud.digitalocean.com/).
2. Navigate to the Marketplace and search for "Pangolin".
3. Click on the Pangolin 1-Click App.
4. Configure your Droplet:
- Choose a plan (recommended: at least 1GB RAM)
- Select a datacenter region
- Add SSH keys for authentication
- Choose a hostname (e.g., pangolin-server)
5. Click "Create Droplet".
### 2. DNS Configuration
Before proceeding with setup, you need to configure your domain to point to your new Droplet:
1. Obtain your Droplet's IP address from the DigitalOcean control panel.
2. Go to your domain registrar or DNS provider.
3. Create an A record that points your domain or subdomain to your Droplet's IP address.
```
Type: A
Name: pangolin (or @ for root domain)
Value: your_droplet_ip
TTL: 3600 (or as low as possible for faster propagation)
```
4. Wait for DNS propagation (can take 5 minutes to several hours).
### 3. Initial Setup
1. Once your Droplet is created, connect to it via SSH:
```bash
ssh root@your_droplet_ip
```
2. The first-login setup script will run automatically, guiding you through the initial configuration:
- Enter your domain name
- Provide your email for SSL certificates
- The script will run the Pangolin installer
3. After the installer completes, you'll be able to access the Pangolin dashboard.
### 4. Dashboard Setup
1. Open a web browser and navigate to `https://your-domain.com`.
2. Follow the on-screen instructions to:
- Create an admin account
- Set up your organization
- Configure your first site
### 5. Connecting Remote Sites
Pangolin allows you to connect remote sites using either the Newt client or standard WireGuard.
#### Using Newt (Recommended)
On your remote site (e.g., home server, private network):
1. Install Newt:
```bash
curl -L https://github.com/fosrl/newt/releases/download/latest/install.sh | sudo bash
```
2. In the Pangolin dashboard:
- Go to Sites > Add Site
- Follow the instructions to generate a configuration
- Copy the provided configuration
3. On your remote site, create a configuration file:
```bash
sudo nano /etc/newt/config.yaml
```
Paste the configuration from the dashboard.
4. Start Newt:
```bash
sudo newt start
```
#### Using WireGuard
1. In the Pangolin dashboard:
- Go to Sites > Add Site
- Select WireGuard configuration
- Download the configuration file
2. On your remote site, install WireGuard:
```bash
# For Ubuntu/Debian
sudo apt install wireguard
# For CentOS/RHEL
sudo yum install wireguard-tools
```
3. Copy the configuration file to `/etc/wireguard/wg0.conf`.
4. Start the WireGuard interface:
```bash
sudo wg-quick up wg0
```
### 6. Exposing Resources
1. In the Pangolin dashboard, go to Resources > Add Resource.
2. Configure your resource:
- Name: A descriptive name
- Type: HTTP/HTTPS, TCP, or UDP
- Target: The IP and port of the service on your private site
- Domain: The domain or subdomain to access the resource
- Access Control: Set authentication and permission rules
3. Save the resource configuration.
4. Your private resource is now securely accessible through Pangolin.
### 7. Security Considerations
- The Pangolin Droplet comes with UFW firewall pre-configured to allow only necessary ports.
- Set up 2FA for your admin account in the Pangolin dashboard.
- Consider setting up CrowdSec for additional protection against brute force attacks.
- Regularly update your Pangolin installation with the latest security patches.
### 8. Maintenance and Updates
To update Pangolin in the future:
1. SSH into your Droplet:
```bash
ssh root@your_droplet_ip
```
2. Update the installer:
```bash
cd /opt/pangolin
wget -O installer "https://github.com/fosrl/pangolin/releases/download/latest/installer_linux_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')"
chmod +x ./installer
```
3. Run the installer:
```bash
./installer -y
```
## Troubleshooting
### Cannot Access Dashboard
1. Verify DNS configuration with `dig your-domain.com`.
2. Check that your domain points to your Droplet's IP address.
3. Ensure SSL certificates were issued correctly:
```bash
cd /opt/pangolin
docker compose logs traefik
```
### Connection Issues from Remote Sites
1. Verify the WireGuard/Newt tunnel is active:
```bash
# For WireGuard
sudo wg show
# For Newt
sudo newt status
```
2. Check firewall settings on both the Pangolin server and remote site.
3. Verify network connectivity with `ping` or `traceroute`.
## Need Help?
- Documentation: [https://docs.fossorial.io](https://docs.fossorial.io)
- Discord Community: [https://discord.gg/HCJR8Xhme4](https://discord.gg/HCJR8Xhme4)
- GitHub Issues: [https://github.com/fosrl/pangolin/issues](https://github.com/fosrl/pangolin/issues)
- Email Support: [numbat@fossorial.io](mailto:numbat@fossorial.io)

View file

@ -0,0 +1,7 @@
#!/bin/bash
set -e
# Install Docker
echo "Installing Docker..."
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

View file

@ -0,0 +1,16 @@
#!/bin/sh
cat >> /etc/ssh/sshd_config <<EOM
Match User root
ForceCommand echo "Please wait while we get your droplet ready..."
EOM
# If your build uses this script add the following code snippet
# to your cloud-init scripts
# /var/lib/cloud/scripts/per-instance/onboot/001_onboot
# # Remove the ssh force logout command
# sed -e '/Match User root/d' \
# -e '/.*ForceCommand.*droplet.*/d' \
# -i /etc/ssh/sshd_config
#
# systemctl restart ssh

View file

@ -0,0 +1,22 @@
#!/bin/sh
################################
## PART: Write the application tag
##
## vi: syntax=sh expandtab ts=4
build_date=$(date +%Y-%m-%d)
distro="$(lsb_release -s -i)"
distro_release="$(lsb_release -s -r)"
distro_codename="$(lsb_release -s -c)"
distro_arch="$(uname -m)"
cat >> /var/lib/digitalocean/application.info <<EOM
application_name="${application_name}"
build_date="${build_date}"
distro="${distro}"
distro_release="${distro_release}"
distro_codename="${distro_codename}"
distro_arch="${distro_arch}"
application_version="${application_version}"
EOM

View file

@ -0,0 +1,45 @@
#!/bin/bash
# Ensure /tmp exists and has the proper permissions before
# checking for security updates
# https://github.com/digitalocean/marketplace-partners/issues/94
if [[ ! -d /tmp ]]; then
mkdir /tmp
fi
chmod 1777 /tmp
apt-get -y update
apt-get -y upgrade
rm -rf /tmp/* /var/tmp/*
history -c
cat /dev/null > /root/.bash_history
unset HISTFILE
apt-get -y autoremove
apt-get -y autoclean
find /var/log -mtime -1 -type f -exec truncate -s 0 {} \;
rm -rf /var/log/*.gz /var/log/*.[0-9] /var/log/*-????????
rm -rf /var/lib/cloud/instances/*
rm -f /root/.ssh/authorized_keys /etc/ssh/*key*
touch /etc/ssh/revoked_keys
chmod 600 /etc/ssh/revoked_keys
# Securely erase the unused portion of the filesystem
GREEN='\033[0;32m'
NC='\033[0m'
printf "\n${GREEN}Writing zeros to the remaining disk space to securely
erase the unused portion of the file system.
Depending on your disk size this may take several minutes.
The secure erase will complete successfully when you see:${NC}
dd: writing to '/zerofile': No space left on device\n
Beginning secure erase now\n"
dd if=/dev/zero of=/zerofile &
PID=$!
while [ -d /proc/$PID ]
do
printf "."
sleep 5
done
sync; rm /zerofile; sync
cat /dev/null > /var/log/lastlog; cat /dev/null > /var/log/wtmp
sudo apt-get --yes purge droplet-agent*

129
pangolin-24-04/README.md Normal file
View file

@ -0,0 +1,129 @@
# Pangolin DigitalOcean Marketplace 1-Click App
This repository contains Packer templates and scripts to build a DigitalOcean Marketplace 1-Click App for [Pangolin](https://github.com/fosrl/pangolin), a self-hosted tunneled mesh reverse proxy with access control.
## Prerequisites
- [Packer](https://www.packer.io/downloads) (v1.7.0 or higher)
- [DigitalOcean Personal Access Token](https://docs.digitalocean.com/reference/api/create-personal-access-token/)
- The [DigitalOcean Packer plugin](https://developer.hashicorp.com/packer/plugins/builders/digitalocean) (for Packer 1.7.0+)
## Directory Structure
```
pangolin-marketplace/
├── common/
│ ├── files/
│ │ └── var/
│ │ └── lib/
│ │ └── digitalocean/
│ └── scripts/
│ ├── 010-docker.sh
│ ├── 018-force-ssh-logout.sh
│ ├── 020-application-tag.sh
│ └── 900-cleanup.sh
└── pangolin-24-04/
├── files/
│ └── etc/
│ └── update-motd.d/
│ └── 99-one-click
├── scripts/
│ ├── 010-pangolin.sh
│ └── 020-firewall.sh
└── template.json
```
## Building the Image
1. Clone this repository:
```bash
git clone https://github.com/your-username/pangolin-marketplace.git
cd pangolin-marketplace
```
2. For Packer 1.7.0+, initialize the DigitalOcean plugin:
```bash
# Create plugins.pkr.hcl file
cat > plugins.pkr.hcl << EOF
packer {
required_plugins {
digitalocean = {
version = ">= 1.0.4"
source = "github.com/digitalocean/digitalocean"
}
}
}
EOF
# Initialize plugins
packer init plugins.pkr.hcl
```
3. Set your DigitalOcean API token as an environment variable:
```bash
export DIGITALOCEAN_API_TOKEN=your_digitalocean_token
```
4. Create the necessary directory structure if it doesn't already exist:
```bash
mkdir -p common/files/var/lib/digitalocean
mkdir -p pangolin-24-04/files/etc/update-motd.d
```
5. Validate the template:
```bash
packer validate pangolin-24-04/template.json
```
6. Build the image:
```bash
packer build pangolin-24-04/template.json
```
7. The build will output a snapshot ID. Note this ID for submission to the Marketplace.
## Submitting to the DigitalOcean Marketplace
1. Log in to the [DigitalOcean Vendor Portal](https://cloud.digitalocean.com/vendorportal).
2. Submit your app with the following details:
- **Name**: Pangolin
- **Version**: 1.2.0
- **Software Included**:
- Pangolin 1.2.0
- Docker CE (latest)
- **Image ID**: [The snapshot ID from the Packer build]
3. Complete the rest of the submission form with relevant details about Pangolin.
## For End Users
Once the image is approved and available in the Marketplace, users can deploy Pangolin by:
1. Selecting "Pangolin" from the DigitalOcean Marketplace.
2. Creating a Droplet based on the image.
3. Pointing a domain to the Droplet's IP address.
4. SSH'ing into the Droplet, where they'll be guided through initial setup.
## Troubleshooting
If you encounter issues during the build:
1. Add the `-debug` flag to prompt for confirmation at each build step:
```bash
packer build -debug pangolin-24-04/template.json
```
2. Use the `-on-error=ask` flag to debug failed builds:
```bash
packer build -on-error=ask pangolin-24-04/template.json
```
3. Enable verbose logging:
```bash
PACKER_LOG=1 packer build pangolin-24-04/template.json
```
## License
Pangolin is dual licensed under the AGPL-3 and the Fossorial Commercial license.

View file

@ -0,0 +1,27 @@
#!/bin/sh
#
# Configured as part of the DigitalOcean 1-Click Image build process
myip=$(hostname -I | awk '{print$1}')
cat <<EOF
********************************************************************************
Welcome to DigitalOcean's 1-Click Pangolin Droplet.
To keep this Droplet secure, the UFW firewall is enabled.
All ports are BLOCKED except 22 (SSH), 80 (HTTP), 443 (HTTPS), and 51820 (WireGuard).
In a web browser, after completing setup, you can access:
* The Pangolin Dashboard: https://YOUR_DOMAIN
* Documentation: https://docs.fossorial.io
On first login, you'll be guided through the Pangolin setup process to:
1. Configure your domain
2. Set up SSL certificates
3. Complete the installation
For help and more information, visit: https://github.com/fosrl/pangolin
Or join the community: https://discord.gg/HCJR8Xhme4
********************************************************************************
To delete this message of the day: rm -rf $(readlink -f ${0})
EOF

View file

@ -0,0 +1,138 @@
#!/bin/bash
set -e
# Create directories for Pangolin
mkdir -p /opt/pangolin
# Download the Pangolin installer
echo "Downloading Pangolin installer..."
wget -O /opt/pangolin/installer "https://github.com/fosrl/pangolin/releases/download/${application_version}/installer_linux_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')"
chmod +x /opt/pangolin/installer
# Create first-login setup script
cat > /opt/pangolin/setup.sh << 'EOF'
#!/bin/bash
# Colors for better UI
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
clear
echo -e "${BLUE}=================================================================${NC}"
echo -e "${GREEN}Welcome to Pangolin - Tunneled Mesh Reverse Proxy${NC}"
echo -e "${BLUE}=================================================================${NC}"
echo ""
echo -e "This script will help you set up Pangolin on your DigitalOcean Droplet."
echo ""
echo -e "${YELLOW}Important:${NC} Before continuing, make sure you have:"
echo " 1. A domain name pointing to this server's IP address"
echo " 2. Your email address for LetsEncrypt SSL certificates"
echo ""
read -p "Press Enter to continue..."
# Get domain and email
echo ""
echo -e "${BLUE}Domain Configuration${NC}"
echo -e "Please enter the domain name you want to use with Pangolin."
echo -e "This domain should already be pointing to this server's IP: $(curl -s ifconfig.me)"
echo ""
read -p "Domain (e.g., pangolin.example.com): " DOMAIN
echo ""
echo -e "${BLUE}Email Configuration${NC}"
echo -e "Please enter your email address for LetsEncrypt SSL certificates."
echo ""
read -p "Email: " EMAIL
# Run the installer
echo ""
echo -e "${BLUE}Running Pangolin Installer...${NC}"
echo ""
cd /opt/pangolin
./installer -y
# Post-installation info
echo ""
echo -e "${GREEN}Pangolin has been installed successfully!${NC}"
echo ""
echo -e "${YELLOW}Important Next Steps:${NC}"
echo "1. Access Pangolin at: https://$DOMAIN"
echo "2. Complete the initial setup wizard in your browser"
echo "3. See the documentation at: https://docs.fossorial.io"
echo ""
echo -e "${BLUE}Thank you for using Pangolin from the DigitalOcean Marketplace.${NC}"
echo ""
# Remove this script from .bashrc
sed -i '/setup.sh/d' /root/.bashrc
EOF
chmod +x /opt/pangolin/setup.sh
# Add to root's .bashrc to run on first login
echo "# Run Pangolin setup on first login" >> /root/.bashrc
echo "if [ -f /opt/pangolin/setup.sh ]; then" >> /root/.bashrc
echo " /opt/pangolin/setup.sh" >> /root/.bashrc
echo "fi" >> /root/.bashrc
# Create per-instance startup script
mkdir -p /var/lib/cloud/scripts/per-instance
cat > /var/lib/cloud/scripts/per-instance/01-setup-pangolin.sh << 'EOF'
#!/bin/bash
# This script runs on first boot of a newly created Droplet
# to prepare the system for Pangolin setup
# Set the hostname to 'pangolin'
hostnamectl set-hostname pangolin
# Ensure Docker is running
systemctl enable docker
systemctl start docker
EOF
chmod +x /var/lib/cloud/scripts/per-instance/01-setup-pangolin.sh
# Create a README file in /opt/pangolin
cat > /opt/pangolin/README.md << 'EOF'
# Pangolin - Tunneled Mesh Reverse Proxy
Welcome to your Pangolin server! This guide will help you get started.
## What is Pangolin?
Pangolin is a self-hosted tunneled mesh reverse proxy server with identity and access control, designed to securely expose private resources on distributed networks. It connects isolated networks through encrypted tunnels, enabling easy access to remote services without opening ports.
## Key Features
- Expose private resources without opening ports (firewall punching)
- Secure site-to-site connectivity via WireGuard tunnels
- Automated SSL certificates via LetsEncrypt
- Support for HTTP/HTTPS and raw TCP/UDP services
- Centralized authentication system
- Role-based access control
## Getting Started
1. When you first log in, the setup script will guide you through the initial configuration.
2. Make sure your domain is pointing to this server's IP address before running the setup.
3. After completing the setup, you can access the Pangolin dashboard at `https://your-domain.com`.
## Documentation
For detailed documentation, visit: https://docs.fossorial.io
## Support
Need help? Join the community:
- Discord: https://discord.gg/HCJR8Xhme4
- Email: numbat@fossorial.io
- GitHub: https://github.com/fosrl/pangolin
EOF
echo "Pangolin installation files prepared."

View file

@ -0,0 +1,28 @@
#!/bin/bash
set -e
# Configure firewall
echo "Configuring firewall..."
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 51820/udp # WireGuard
ufw --force enable
# Install and configure fail2ban
echo "Configuring fail2ban..."
apt-get install -y fail2ban
cat > /etc/fail2ban/jail.local << EOF
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
[sshd]
enabled = true
EOF
systemctl enable fail2ban
systemctl restart fail2ban

View file

@ -0,0 +1,72 @@
{
"variables": {
"do_api_token": "{{env `DIGITALOCEAN_API_TOKEN`}}",
"image_name": "pangolin-24-04-snapshot-{{timestamp}}",
"apt_packages": "apt-transport-https ca-certificates curl software-properties-common gnupg lsb-release ufw fail2ban",
"application_name": "Pangolin",
"application_version": "1.2.0"
},
"sensitive-variables": ["do_api_token"],
"builders": [
{
"type": "digitalocean",
"api_token": "{{user `do_api_token`}}",
"image": "ubuntu-24-04-x64",
"region": "ams3",
"size": "s-1vcpu-512mb-10gb",
"ssh_username": "root",
"snapshot_name": "{{user `image_name`}}"
}
],
"provisioners": [
{
"type": "shell",
"inline": [
"cloud-init status --wait"
]
},
{
"type": "file",
"source": "common/files/var/",
"destination": "/var/"
},
{
"type": "file",
"source": "pangolin-24-04/files/etc/",
"destination": "/etc/"
},
{
"type": "shell",
"environment_vars": [
"DEBIAN_FRONTEND=noninteractive",
"LC_ALL=C",
"LANG=en_US.UTF-8",
"LC_CTYPE=en_US.UTF-8"
],
"inline": [
"apt -qqy update",
"apt -qqy -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold' full-upgrade",
"apt -qqy -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold' install {{user `apt_packages`}}",
"apt-get -qqy clean"
]
},
{
"type": "shell",
"environment_vars": [
"application_name={{user `application_name`}}",
"application_version={{user `application_version`}}",
"DEBIAN_FRONTEND=noninteractive",
"LC_ALL=C",
"LANG=en_US.UTF-8",
"LC_CTYPE=en_US.UTF-8"
],
"scripts": [
"common/scripts/010-docker.sh",
"pangolin-24-04/scripts/010-pangolin.sh",
"pangolin-24-04/scripts/020-firewall.sh",
"common/scripts/020-application-tag.sh",
"common/scripts/900-cleanup.sh"
]
}
]
}