:::info
Please refer to [No-IP auto update](https://hackmd.io/rK8zrvuKRi6LBuAviBLS9Q) for automatic updating No-IP hostname.
:::
# Complete Guide: FRP, Nginx, Certbot, and WireGuard Setup
This guide provides step-by-step instructions to set up:
- **FRP (Fast Reverse Proxy)** for NAT traversal.
- **Nginx** with **Certbot** for HTTPS.
- **WireGuard** on Raspberry Pi OS 64-bit using PiVPN.
- Additional configurations for SSH forwarding and more.
---
[TOC]
---
## Prerequisites
1. **EC2 Instance (Amazon Linux 2):**
- Public IP and domain name (`ec2-cwbw.ddns.net`).
- Ports opened: `80 (HTTP)`, `443 (HTTPS)`, `2222 (SSH forwarding)`, `7000 (FRP)`, `8484 (GameServer)`, `8585 (GameServer)`, `8586 (GameServer)`, `8596 (GameServer)`, `51820 (WireGuard VPN (UDP))`.

2. **MyHomeServer (Raspberry Pi OS 64-bit):**
- No public IP.
- Services running on ports: `22 (SSH)`, `8080 (HTTP)`, `8081 (HTTP)`, `8484 (GameServer)`, `8585 (GameServer)`, `8586 (GameServer)`, `8596 (GameServer)`, `51820 (WireGuard VPN (UDP))`.
3. **FRP Version:** `0.61.1`.
---
## Step 1: Install and Configure FRP
### On EC2 (FRP Server):
1. **Download and Install FRP:**
```bash
cd ~
wget https://github.com/fatedier/frp/releases/download/v0.61.1/frp_0.61.1_linux_amd64.tar.gz
tar -zxvf frp_0.61.1_linux_amd64.tar.gz
cd frp_0.61.1_linux_amd64
```
2. **Configure FRP Server (`~/frp_0.61.1_linux_amd64/frps.ini`):**
```ini
[common]
bind_port = 7000
```
3. **Set Up FRP as a Systemd Service:**
- Create a systemd service file:
```bash
sudo nano /etc/systemd/system/frps.service
```
- Add the following content:
```ini
[Unit]
Description=FRP Server
After=network.target
[Service]
User=ec2-user
WorkingDirectory=/home/ec2-user/frp_0.61.1_linux_amd64
ExecStart=/home/ec2-user/frp_0.61.1_linux_amd64/frps -c /home/ec2-user/frp_0.61.1_linux_amd64/frps.ini
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
```
- Reload systemd and start the service:
```bash
sudo systemctl daemon-reload
sudo systemctl start frps
sudo systemctl enable frps
```
---
### On MyHomeServer (FRP Client):
1. **Download and Install FRP:**
```bash
cd ~
wget https://github.com/fatedier/frp/releases/download/v0.61.1/frp_0.61.1_linux_arm64.tar.gz
tar -zxvf frp_0.61.1_linux_arm64.tar.gz
cd frp_0.61.1_linux_arm64
```
2. **Configure FRP Client (`~/frp_0.61.1_linux_arm64/frpc.ini`):**
```ini
[common]
server_addr = {EC2_PUBLIC_IP}
server_port = 7000
[ssh_forwarding]
type = tcp
local_port = 22
remote_port = 2222
[http_8080]
type = tcp
local_port = 8080
remote_port = 8080
[http_8081]
type = tcp
local_port = 8081
remote_port = 8081
[game_8484]
type = tcp
local_port = 8484
remote_port = 8484
[game_8585]
type = tcp
local_port = 8585
remote_port = 8585
[game_8586]
type = tcp
local_port = 8586
remote_port = 8586
[game_8596]
type = tcp
local_port = 8596
remote_port = 8596
[wireguard_51820]
type = udp
local_port = 51820
remote_port = 51820
```
3. **Set Up FRP as a Systemd Service:**
- Create a systemd service file:
```bash
sudo nano /etc/systemd/system/frpc.service
```
- Add the following content:
```ini
[Unit]
Description=FRP Client
After=network.target
[Service]
User=pi
WorkingDirectory=/home/pi/frp_0.61.1_linux_arm64
ExecStart=/home/pi/frp_0.61.1_linux_arm64/frpc -c /home/pi/frp_0.61.1_linux_arm64/frpc.ini
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
```
- Reload systemd and start the service:
```bash
sudo systemctl daemon-reload
sudo systemctl start frpc
sudo systemctl enable frpc
```
---
## Step 2: Install Nginx and Certbot on EC2
### 1. **Install Nginx:**
```bash
sudo yum install nginx -y
```
### 2. **Start and Enable Nginx:**
```bash
sudo systemctl start nginx
sudo systemctl enable nginx
```
### 3. **Install Certbot:**
```bash
sudo yum install certbot python3-certbot-nginx -y
```
### 4. **Obtain SSL Certificate:**
Run Certbot to obtain the SSL certificate and configure Nginx for HTTPS:
```bash
sudo certbot --nginx -d ec2-cwbw.ddns.net
```
- Certbot will:
1. Temporarily spin up a web server to validate your domain ownership.
2. Obtain the SSL certificate from Let’s Encrypt.
3. Modify your Nginx configuration to include the certificate and set up HTTPS.
### 5. **Complete Nginx Configuration:**
After Certbot has configured SSL, you can safely edit your Nginx configuration (`/etc/nginx/nginx.conf`) to add custom settings (e.g., reverse proxy rules for `8080` and `8081`).
Example configuration:
```nginx
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name ec2-cwbw.ddns.net;
# Redirect all HTTP requests to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name ec2-cwbw.ddns.net;
# SSL certificates (added by Certbot)
ssl_certificate /etc/letsencrypt/live/ec2-cwbw.ddns.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ec2-cwbw.ddns.net/privkey.pem;
# SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Proxy for 127.0.0.1:8080
location /8080/ {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Proxy for 127.0.0.1:8081
location /8081/ {
proxy_pass http://127.0.0.1:8081/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
}
}
```
6. **Reload Nginx:**
```bash
sudo systemctl reload nginx
```
---
## Step 3: Automate Certbot Certificate Renewal
Certbot typically sets up a cron job in `/etc/cron.d/certbot` to automatically renew certificates. Here’s how to verify and set it up:
### 1. **Check for the Certbot Cron Job:**
```bash
cat /etc/cron.d/certbot
```
- If you see a line like this, the cron job is already set up:
```
0 0,12 * * * root /usr/bin/certbot renew --quiet
```
- If the file doesn’t exist or is empty, proceed to the next step.
### 2. **Add the Certbot Cron Job (if missing):**
#### Ubuntu
```bash
sudo nano /etc/cron.d/certbot
```
#### Amazon Linux
```bash
sudo crontab -e
```
Add the following line:
```
0 0,12 * * * root /usr/bin/certbot renew --quiet
```
- This cron job runs twice a day (at midnight and noon) to check if the certificate needs renewal.
- The `--quiet` flag ensures Certbot doesn’t produce unnecessary output.
### 3. **Test the Renewal Process:**
```bash
sudo certbot renew --dry-run
```
- If the dry run succeeds, the cron job will work as expected.
- If it fails, check the logs for errors:
```bash
sudo journalctl -u certbot
```
---
## Step 4: Install WireGuard on Raspberry Pi OS 64-bit
1. **Install PiVPN:**
```bash
curl -L https://install.pivpn.io | bash
```
2. **Follow the PiVPN Wizard:**
- Select `WireGuard` as the VPN protocol.
- Configure the VPN settings as needed.
3. **Start WireGuard:**
```bash
sudo systemctl start wg-quick@wg0
sudo systemctl enable wg-quick@wg0
```
---
## Step 5: Verify the Setup
1. **Access Services:**
- HTTP/HTTPS: `https://ec2-cwbw.ddns.net:8080/` and `https://ec2-cwbw.ddns.net:8081/`.
- Game Servers: Use the respective ports (`8484`, `8585`, `8586`, `8596`) on the EC2 public IP.
- WireGuard: Connect to `ec2-cwbw.ddns.net:51820`.
- SSH: Use `ec2-cwbw.ddns.net:2222` to access MyHomeServer SSH.
- Example `.ssh/config`
```
Host rpi4-ec2-cwbw
HostName ec2-cwbw.ddns.net
port 2222
User pi
PreferredAuthentications publickey
IdentityFile /Users/brad/.ssh/rpi4
ServerAliveInterval 60
ServerAliveCountMax 3
TCPKeepAlive yes
```
2. **Test FRP:**
- Ensure all forwarded ports are accessible.
---
## Step 6: Add More Ports to FRP
To add more ports, edit the `frpc.ini` file on MyHomeServer and add new sections. For example:
```ini
[custom_port_9000]
type = tcp
local_port = 9000
remote_port = 9000
```
Restart the FRP client:
```bash
sudo systemctl restart frpc
```
---
## Conclusion
You now have a fully functional setup with:
- FRP for NAT traversal.
- Nginx with Certbot for HTTPS.
- WireGuard for secure VPN access.
- Additional configurations for SSH and more.