使用 Tailscale + VPS 反代实现内网服务公网访问
在家庭网络环境中,如果没有公网 IP,但又想对外发布服务,有多种方式可以实现。本文介绍通过 Tailscale 组网,使用 VPS 反向代理来实现访问内网服务的方案。
在本教程中,我们将内网服务器与 vps 组网,然后通过 vps 的公网地址访问内网博客。该方案的访问容量主要受内网的上传带宽限制,家庭宽带上传大多被限制在 60Mbps 以下,轻量级网络服务没有任何问题。
测试环境
- VPS :Ubuntu 22.04.5、nginx 1.18
- 本地:Debian 13、nginx 1.18、PHP 8.4、WordPress blog
- 域名:blog.example.com
域名配置
将申请的域名迁移到 Cloudflare,添加 DNS 记录,并打开代理。
VPS 配置
推荐使用低延迟 vps,有助于提升网络的响应速度。
1. 安装 nginx
apt install nginx -y2. 申请域名证书
apt install certbot python3-certbot-nginx -y
certbot --nginx -d blog.example.com3. 组建虚拟内网
打开 tailscale.com,注册账号并新建虚拟内网,将两台主机都加入同一内网。
在两台主机上分别安装 tailscale:
curl -fsSL https://tailscale.com/install.sh | sh启动 tailscale 并认证:
sudo tailscale up组网成功以后,在 vps 上 ping 内网服务器的 tailscale ip,检查是否连通。
注意:两个节点的“禁用密钥过期”选项必须选中,以防止密钥过期后,连接失效。
4. VPS 反代设置
在 /etc/nginx/sites-available 目录,新建一个以域名命名的文件,如 blog.example.com,文件内容如下:
server {
if ($host = blog.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name blog.example.com;
return 301 https://$host$request_uri;
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 https;
}
server {
listen 443 ssl http2;
server_name blog.example.com;
ssl_certificate /etc/letsencrypt/live/blog.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/blog.example.com/privkey.pem; # managed by Certbot
location / {
proxy_pass http://100.105.151.88:80; # Debian13 Tailscale IP
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 https;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}保存,运行以下命令让反代设置生效:
ln -s /etc/nginx/sites-available/blog.example.com /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx本地设置
1. 安装基础环境
apt update
apt install -y nginx php-fpm php-mysql php-gd php-curl php-mbstring php-xml php-zip mariadb-server unzip2. 配置数据库
进入 sql 数据库环境:
mysql数据库信息如下:
- 数据库名:wordpress
- 用户名:wpuser
- 密码:112233
- 主机:localhost
输入以下命令建立上面的数据库:
CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8mb4;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY '112233';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;查看数据库:
SHOW DATABASES;退出数据库:
exit3. 安装 phpMyAdmin
为方便对数据库进行可视化操作,建议安装 phpMyAdmin。
cd /usr/share
sudo wget https://www.phpmyadmin.net/downloads/phpMyAdmin-latest-all-languages.tar.gz
sudo tar xvf phpMyAdmin-latest-all-languages.tar.gz
sudo mv phpMyAdmin-*-all-languages phpmyadmin
sudo rm phpMyAdmin-latest-all-languages.tar.gz
sudo mkdir /usr/share/phpmyadmin/tmp
sudo chown -R www-data:www-data /usr/share/phpmyadmin/tmp
sudo chmod 777 /usr/share/phpmyadmin/tmp打开浏览器访问:http://<Debian-IP>/phpmyadmin,输入数据库用户名和密码即可访问 phpMyAdmin。
4. 禁用 apache
在 Debian 13 上,Apache 默认占用 80 端口。查看 80 端口是否被占用:
ss -lntp | grep :80如果显示以下信息,则 80 端口被 apache 占用:
LISTEN 0 511 0.0.0.0:80 users:(("apache2",pid=xxx,fd=4))禁用 apache,以便释放 80 端口给 wordpress 使用。
systemctl stop apache2
systemctl stop apache2.socket
systemctl stop apache2.service
systemctl disable apache2
systemctl disable apache2.socket
systemctl disable apache2.service如果不需要 apache,可以直接卸载:
apt purge -y apache2 apache2-utils apache2-bin apache2.2-common
apt autoremove -y5. 安装 wordpress
cd /var/www
wget https://wordpress.org/latest.tar.gz
tar xzf latest.tar.gz
cp -a wordpress/* /var/www/html/
chown -R www-data:www-data /var/www/html
find /var/www/html -type d -exec chmod 755 {} \;
find /var/www/html -type f -exec chmod 644 {} \;确保 WordPress 安装在 /var/www/html 目录下。安装完成后,访问 http://<Debian-IP>/wp-admin/install.php,根据提示完成博客的配置。
6. Nginx 设置
新建 /etc/nginx/sites-available/wordpress 文件,内容如下:
server {
listen 80;
server_name _;
root /var/www/html;
index index.php index.html;
client_max_body_size 256M;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires max;
log_not_found off;
}
location /phpmyadmin {
root /usr/share/;
index index.php index.html index.htm;
location ~ ^/phpmyadmin/(.+\.php)$ {
try_files $uri =404;
root /usr/share/;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
root /usr/share/;
}
}
}保存后重载 Nginx:
nginx -t && systemctl reload nginx7. 修改站点地址
浏览器输入:http://<Debian-IP>/wp-login.php,登录 WordPress 后台,找到 设置 > 常规,将 WordPress 地址 和 站点地址 修改为 https://blog.example.com 并保存。
现在可以用 https://blog.example.com 地址访问内网博客了。
其他问题
1. 访问异常
一般的网络服务到这就能正常访问,但 WordPress 使用 SSL + 反向代理时可能会遇到样式丢失问题。可以修改 wp-config.php 文件来解决。
在这段代码之前,
/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';添加以下内容:
define('WP_HOME', 'https://blog.example.com');
define('WP_SITEURL', 'https://blog.example.com');
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}保存即可。
2. 调整上传限制
修改 PHP 上传限制。
先确认 PHP 版本:
php -v假设是 PHP 8.4,编辑配置:
nano /etc/php/8.4/fpm/php.ini找到并修改下面 3 项:
upload_max_filesize = 256M
post_max_size = 256M
memory_limit = 512M
max_execution_time = 300
max_input_time = 300如果数据库备份 > 256M,可以改成 512M 或 1024M。
修改完成,重启 PHP-FPM:
systemctl restart php8.4-fpm3. 修改 Nginx 上传限制
编辑 WordPress/phpMyAdmin 所在的 server:
nano /etc/nginx/sites-enabled/wordpress在 server {} 里加一行:
client_max_body_size 256M;例如:
server {
listen 80;
server_name blog.example.com;
client_max_body_size 256M;
...
}修改完成,重启 Nginx:
nginx -t && systemctl reload nginx4. 限制内网访问
如果不想让内网访问到博客,可以在 Nginx 中限制访问的源 IP,例如只让 vps 的 tailscale IP 访问。
nano /etc/nginx/sites-enabled/wordpress在 server {} 里加 allow / deny:
例如:
server {
listen 80;
server_name blog.example.com;
# 只允许 VPS 的 Tailscale IP
allow 100.127.66.5;
deny all;
client_max_body_size 256M;
...
}修改完成,重启 Nginx:
nginx -t && systemctl reload nginx 觉得内容不错?我要