打通内网与外网
1.FRP基本介绍
内网穿透是一种通过公共网络(例如互联网)连接两个私有网络的技术,使得外部用户可以访问内部网络中的服务。FRP(Fast Reverse Proxy)是一种流行的内网穿透工具,其技术思想和优势如下:
1.1需求资源
- 一台外网可访问的有固定ip的云服务器
- 一台外网无法访问的无固定ip的本地设备(家用电脑、NAS等)
需求:将云服务器搭建为一台内网穿透服务器,实现通过外网访问本地设备(网页、数据库)的功能。且即使没有域名也可通过公网访问
1.2技术思想
- 反向代理(Reverse Proxy) :FRP利用反向代理的思想,在公共服务器上部署一个中转服务器(即FRP服务器),外部用户通过该中转服务器与内部网络建立连接。
- 端口映射和流量转发:FRP将外部请求映射到内网机器上的指定端口,然后将流量从公网传输到内网,实现数据传输。
- 心跳检测和保持连接:FRP通过心跳检测机制保持与客户端和服务端之间的稳定连接,确保数据传输的可靠性和稳定性。
1.3优势
- 穿透防火墙和NAT:FRP可以穿透防火墙和NAT设备,使得位于不同网络环境中的主机能够互相通信,解决了企业内外网络隔离的问题。
- 灵活性和易用性:FRP配置简单灵活,支持多种协议(TCP、UDP等),可根据需求灵活配置端口映射和访问控制等参数。
- 安全性:通过加密传输数据、访问控制列表等安全机制,保障数据传输的安全性,防止未经授权的访问。
- 跨平台支持:FRP支持多种操作系统(Windows、Linux、Mac等),可以在不同平台上运行,并且提供了丰富的功能和插件扩展。
- 开源社区支持:FRP是开源项目,拥有活跃的社区支持和更新,用户可以获取最新版本、bug修复以及安全更新。
总而言之,FRP作为一种内网穿透工具,在网络通信方面具有良好的稳定性、灵活性和安全性,为用户提供了便捷的远程访问解决方案。
2.部署FRP
2.1安装包
Windows:https://github.com/fatedier/frp/releases/download/v0.61.1/frp_0.61.1_windows_amd64.zip
Linux:https://github.com/fatedier/frp/releases/download/v0.61.1/frp_0.61.1_linux_amd64.tar.gz
# 或使用命令下载,二选一
wget https://github.com/fatedier/frp/releases/download/v0.61.1/frp_0.61.1_linux_amd64.tar.gz
mwget https://github.com/fatedier/frp/releases/download/v0.61.1/frp_0.61.1_linux_amd64.tar.gz
2.2配置文件
# 1.服务端配置
# 启动命令:./frps -c frps.toml
# frps.toml
bindPort = 7000 # frp服务的特定端口,防火墙也需放开该端口
# 服务面板可查看frp服务状态信息
webServer.addr = "0.0.0.0" # 后台管理地址,默认是127.0.0.1,如果是公网访问则改成0.0.0.0
webServer.port = 7500 # 后台管理端口
webServer.user = "admin" # (可选)后台登录用户名
webServer.password = "admin" # (可选)后台登录密码
transport.tls.force = true # 服务端将只接受 TLS链接
auth.method = 'token' # 客户端访问验证方式
auth.token = "54321" # 客户端访问验证密码,frpc要与frps一致,随机密码生成器:https://tool.lu/strrandom/
# 自定义的监听的端口,所有对服务器该端口访问将被转发到本地内网,做了反向代理可不处理防火墙放行
# vhostHTTPPort = 8000
# vhostHTTPSPort = 45443
# 2、客户端配置
# 启动命令:./frpc -c frpc.toml
# frpc.toml
transport.tls.enable = true # 从 v0.50.0版本开始,transport.tls.enable的默认值为 true
serverAddr = "你的云服务器外网IP" # 服务端ip
serverPort = 7000 # 服务端端口
auth.method = 'token' # 客户端访问验证方式
auth.token = '54321' # 客户端访问验证密码
[[proxies]]
name = "nas_mysql" # 客户端服务名
type = "tcp" # 通讯方式
localIP = "127.0.0.1" # 客户端的ip(固定)
localPort = 3306 # 客户端服务端口
remotePort = 13306 # 映射到服务端端口(服务器需放行)
[[proxies]]
name = "test-tcp"
type = "tcp"
localIP = "127.0.0.1" # 需要暴露的服务的IP
localPort = 9000 # 将本地9000端口的服务暴露在公网的6060端口
remotePort = 6060 # 暴露服务的公网入口
[[proxies]]
name = "nas_ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000
#customDomains = ["xxx.xxx.xxx.xxx"]
[[proxies]]
name = "web"
type = "http"
localIP = "127.0.0.1"
localPort = 80
customDomains = ["域名或ip"]
3.配置FRP服务
账号需要有root权限,配置FRP服务主要目的是用于实现开机自启
# 查看系统所有用户 [root@on88888 frp_0.61.1]# cat /etc/passwd root:x:0:0:root:/root:/bin/bash UID = 0:root 用户的特权 UID GID = 0:root 组的特权 GID
3.1创建 FRP 服务端服务文件
# 检查一下目录 /etc/systemd/system 是否存在,不存在则创建一下
# 创建 FRP 服务端服务文件
vim /etc/systemd/system/frps.service
# 配置完service文件重新加载 systemd
sudo systemctl daemon-reload
[Unit]
Description=FRP Server Service
After=network.target
[Service]
Type=simple
User=root
Restart=on-failure
RestartSec=5s
# 确保 frps 有执行权限 sudo chmod +x /opt/module/frp_0.61.1/frps
ExecStart=/opt/module/frp_0.61.1/frps -c /opt/module/frp_0.61.1/frps.toml # 修改为你的frps所在目录
ExecReload=/bin/kill -HUP $MAINPID
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target
3.2创建 FRP 客户端服务文件
# 检查一下目录 /etc/systemd/system 是否存在,不存在则创建一下
# 创建 FRP 客户端服务文件
vim /etc/systemd/system/frpc.service
# 配置完service文件重新加载 systemd
sudo systemctl daemon-reload
[Unit]
Description=FRP Client Service
After=network.target
[Service]
Type=simple
User=root
Restart=on-failure
RestartSec=5s
# 确保 frpc 有执行权限 sudo chmod +x /share/homes/xlqnas/frp/frpc
ExecStart=/share/homes/xlqnas/frp/frpc -c /share/homes/xlqnas/frp/frpc.toml # 修改为你的frpc所在目录
ExecReload=/bin/kill -HUP $MAINPID
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target
3.3创建管理脚本
# 创建管理脚本
vim /usr/local/bin/frp-manager.sh
# 添加脚本权限
sudo chmod +x /usr/local/bin/frp-manager.sh
#!/bin/bash
# ============ 配置区 ============
# 服务名称
FRPS_SERVICE="frps" # 服务端
FRPC_SERVICE="frpc" # 客户端
# 配置文件路径(根据实际修改)
FRPS_CONFIG="/opt/module/frp_0.61.1/frps.toml"
FRPC_CONFIG="/share/homes/xlqnas/frp/frpc.toml"
# ============ 颜色定义 ============
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# ============ 帮助信息 ============
show_help() {
echo -e "${BLUE}FRP 服务管理脚本${NC}"
echo "用法: $0 [mode] {command}"
echo ""
echo "模式 [mode] (可选):"
echo " frps 管理服务端 (默认)"
echo " frpc 管理客户端"
echo " all 同时管理 frps 和 frpc"
echo ""
echo "命令:"
echo " start 启动服务"
echo " stop 停止服务"
echo " restart 重启服务"
echo " status 查看运行状态 (active/inactive)"
echo " enabled-status 查看是否开机自启 (enabled/disabled)"
echo " all-status 查看详细状态 (systemctl status)"
echo " enable 设置开机自启"
echo " disable 禁用开机自启"
echo " logs 查看最近20行日志"
echo " check-config 检查配置文件是否存在"
echo " help | -h 显示此帮助"
echo ""
echo "示例:"
echo " $0 frps status # 查看 frps 运行状态"
echo " $0 frpc enabled-status # 查看 frpc 是否开机自启"
echo " $0 all restart # 重启两个服务"
echo " $0 logs # 默认操作 frps"
}
# ============ 检查配置文件 ============
check_config() {
echo -e "${YELLOW}检查配置文件...${NC}"
local found_error=0
if [[ "$MODE" == "frps" || "$MODE" == "all" ]]; then
if [ -f "$FRPS_CONFIG" ]; then
echo -e "${GREEN}✓ frps.toml 存在: $FRPS_CONFIG${NC}"
else
echo -e "${RED}✗ frps.toml 不存在${NC}"
found_error=1
fi
fi
if [[ "$MODE" == "frpc" || "$MODE" == "all" ]]; then
if [ -f "$FRPC_CONFIG" ]; then
echo -e "${GREEN}✓ frpc.toml 存在: $FRPC_CONFIG${NC}"
else
echo -e "${RED}✗ frpc.toml 不存在${NC}"
found_error=1
fi
fi
return $found_error
}
# ============ 启动服务 ============
start_services() {
echo -e "${YELLOW}启动 FRP 服务...${NC}"
local success=0
if [[ "$MODE" == "frps" || "$MODE" == "all" ]]; then
if systemctl is-active --quiet "$FRPS_SERVICE"; then
echo -e "${GREEN}✓ $FRPS_SERVICE 已在运行${NC}"
else
sudo systemctl start "$FRPS_SERVICE"
if systemctl is-active --quiet "$FRPS_SERVICE"; then
echo -e "${GREEN}✓ $FRPS_SERVICE 启动成功${NC}"
else
echo -e "${RED}✗ $FRPS_SERVICE 启动失败${NC}"
success=1
fi
fi
fi
if [[ "$MODE" == "frpc" || "$MODE" == "all" ]]; then
if systemctl is-active --quiet "$FRPC_SERVICE"; then
echo -e "${GREEN}✓ $FRPC_SERVICE 已在运行${NC}"
else
sudo systemctl start "$FRPC_SERVICE"
if systemctl is-active --quiet "$FRPC_SERVICE"; then
echo -e "${GREEN}✓ $FRPC_SERVICE 启动成功${NC}"
else
echo -e "${RED}✗ $FRPC_SERVICE 启动失败${NC}"
success=1
fi
fi
fi
return $success
}
# ============ 停止服务 ============
stop_services() {
echo -e "${YELLOW}停止 FRP 服务...${NC}"
if [[ "$MODE" == "frps" || "$MODE" == "all" ]]; then
if systemctl is-active --quiet "$FRPS_SERVICE"; then
sudo systemctl stop "$FRPS_SERVICE"
echo -e "${GREEN}✓ $FRPS_SERVICE 已停止${NC}"
else
echo -e "${YELLOW}⚠ $FRPS_SERVICE 未运行${NC}"
fi
fi
if [[ "$MODE" == "frpc" || "$MODE" == "all" ]]; then
if systemctl is-active --quiet "$FRPC_SERVICE"; then
sudo systemctl stop "$FRPC_SERVICE"
echo -e "${GREEN}✓ $FRPC_SERVICE 已停止${NC}"
else
echo -e "${YELLOW}⚠ $FRPC_SERVICE 未运行${NC}"
fi
fi
}
# ============ 重启服务 ============
restart_services() {
echo -e "${YELLOW}重启 FRP 服务...${NC}"
if [[ "$MODE" == "frps" || "$MODE" == "all" ]]; then
sudo systemctl restart "$FRPS_SERVICE"
echo -e "${GREEN}✓ $FRPS_SERVICE 重启完成${NC}"
fi
if [[ "$MODE" == "frpc" || "$MODE" == "all" ]]; then
sudo systemctl restart "$FRPC_SERVICE"
echo -e "${GREEN}✓ $FRPC_SERVICE 重启完成${NC}"
fi
}
# ============ 查看运行状态 ============
status_services() {
echo -e "${YELLOW}FRP 服务运行状态:${NC}"
local any_active=0
if [[ "$MODE" == "frps" || "$MODE" == "all" ]]; then
if systemctl list-unit-files "$FRPS_SERVICE.service" &>/dev/null; then
state=$(systemctl is-active "$FRPS_SERVICE" 2>/dev/null)
if [[ "$state" == "active" ]]; then
echo -e "frps: ${GREEN}active (running)${NC}"
any_active=1
else
echo -e "frps: ${RED}$state${NC}"
fi
else
echo -e "frps: ${RED}未安装(service 不存在)${NC}"
fi
fi
if [[ "$MODE" == "frpc" || "$MODE" == "all" ]]; then
if systemctl list-unit-files "$FRPC_SERVICE.service" &>/dev/null; then
state=$(systemctl is-active "$FRPC_SERVICE" 2>/dev/null)
if [[ "$state" == "active" ]]; then
echo -e "frpc: ${GREEN}active (running)${NC}"
any_active=1
else
echo -e "frpc: ${RED}$state${NC}"
fi
else
echo -e "frpc: ${RED}未安装(service 不存在)${NC}"
fi
fi
return $any_active
}
# ============ 查看是否开机自启 ============
enabled_status() {
echo -e "${YELLOW}FRP 开机自启状态:${NC}"
if [[ "$MODE" == "frps" || "$MODE" == "all" ]]; then
if systemctl list-unit-files "$FRPS_SERVICE.service" &>/dev/null; then
state=$(systemctl is-enabled "$FRPS_SERVICE" 2>/dev/null)
if [[ "$state" == "enabled" ]]; then
echo -e "frps: ${GREEN}enabled (已开机自启)${NC}"
else
echo -e "frps: ${YELLOW}disabled (未开机自启)${NC}"
fi
else
echo -e "frps: ${RED}未安装(service 不存在)${NC}"
fi
fi
if [[ "$MODE" == "frpc" || "$MODE" == "all" ]]; then
if systemctl list-unit-files "$FRPC_SERVICE.service" &>/dev/null; then
state=$(systemctl is-enabled "$FRPC_SERVICE" 2>/dev/null)
if [[ "$state" == "enabled" ]]; then
echo -e "frpc: ${GREEN}enabled (已开机自启)${NC}"
else
echo -e "frpc: ${YELLOW}disabled (未开机自启)${NC}"
fi
else
echo -e "frpc: ${RED}未安装(service 不存在)${NC}"
fi
fi
}
# ============ 查看详细状态 ============
all_status() {
services=()
[[ "$MODE" == "frps" ]] && services+=("$FRPS_SERVICE")
[[ "$MODE" == "frpc" ]] && services+=("$FRPC_SERVICE")
[[ "$MODE" == "all" ]] && services=("$FRPS_SERVICE" "$FRPC_SERVICE")
echo -e "${YELLOW}详细服务状态:${NC}"
sudo systemctl status "${services[@]}" --no-pager -l
}
# ============ 设置开机自启 ============
enable_services() {
echo -e "${YELLOW}设置开机自启...${NC}"
if [[ "$MODE" == "frps" || "$MODE" == "all" ]]; then
sudo systemctl enable "$FRPS_SERVICE" 2>/dev/null && \
echo -e "${GREEN}✓ $FRPS_SERVICE 已设置开机自启${NC}"
fi
if [[ "$MODE" == "frpc" || "$MODE" == "all" ]]; then
sudo systemctl enable "$FRPC_SERVICE" 2>/dev/null && \
echo -e "${GREEN}✓ $FRPC_SERVICE 已设置开机自启${NC}"
fi
}
# ============ 禁用开机自启 ============
disable_services() {
echo -e "${YELLOW}禁用开机自启...${NC}"
if [[ "$MODE" == "frps" || "$MODE" == "all" ]]; then
sudo systemctl disable "$FRPS_SERVICE" 2>/dev/null && \
echo -e "${GREEN}✓ $FRPS_SERVICE 已禁用开机自启${NC}"
fi
if [[ "$MODE" == "frpc" || "$MODE" == "all" ]]; then
sudo systemctl disable "$FRPC_SERVICE" 2>/dev/null && \
echo -e "${GREEN}✓ $FRPC_SERVICE 已禁用开机自启${NC}"
fi
}
# ============ 查看日志 ============
show_logs() {
echo -e "${YELLOW}查看服务日志:${NC}"
if [[ "$MODE" == "frps" || "$MODE" == "all" ]]; then
echo -e "${BLUE}frps 日志 (最近20行):${NC}"
sudo journalctl -u "$FRPS_SERVICE" -n 20 --no-pager --no-hostname
fi
if [[ "$MODE" == "frpc" || "$MODE" == "all" ]]; then
echo -e "${BLUE}frpc 日志 (最近20行):${NC}"
sudo journalctl -u "$FRPC_SERVICE" -n 20 --no-pager --no-hostname
fi
}
# ============ 主逻辑 ============
MODE="frps"
# 解析第一个参数为模式
case "$1" in
frps|frpc|all)
MODE="$1"
shift
;;
help|--help|-h)
show_help
exit 0
;;
"")
show_help
exit 0
;;
esac
COMMAND="$1"
if [ -z "$COMMAND" ]; then
show_help
exit 1
fi
# 执行命令
case "$COMMAND" in
start)
start_services
;;
stop)
stop_services
;;
restart)
restart_services
;;
status)
status_services
;;
enabled-status)
enabled_status
;;
all-status)
all_status
;;
enable)
enable_services
;;
disable)
disable_services
;;
logs)
show_logs
;;
check-config)
check_config
;;
help|--help|-h)
show_help
exit 0
;;
*)
echo -e "${RED}❌ 未知命令: $COMMAND${NC}"
show_help
exit 1
;;
esac
3.4验证服务
# 检查服务是否正常运行
systemctl is-active frps
systemctl is-active frpc
# 检查开机自启是否设置
systemctl is-enabled frps
systemctl is-enabled frpc
3.5常用命令示例
# 设置开机自启(仅 frps)
frp-manager.sh frps enable
# 启动服务(仅 frps)
frp-manager.sh frps start
# 查看状态(仅 frps)
frp-manager.sh frps status
# 查看详细状态(仅 frps)
frp-manager.sh frps all-status
# 查看日志
frp-manager.sh frps logs
# 重启服务
frp-manager.sh frps restart
NAS系统设置
1.时区设置
# 在当前会话中设置时区(临时生效)
export TZ='CST-8'
# 验证时间
date
# 如果要永久生效,添加到启动文件中
echo "export TZ='CST-8'" >> ~/.profile
echo "export TZ='CST-8'" >> ~/.bashrc
# 加载配置并验证时间
source ~/.profile ~/.bashrc && date
2.在 QNAP 上管理 frpc
[xlqnas@NAS7D955B ~]$ uname -a
Linux NAS7D955B 5.10.60-qnap #1 SMP Sat Aug 12 09:01:13 CST 2023 x86_64 GNU/Linux
# QNAP NAS(威联通网络存储设备)
# 这是一个基于 Linux 的嵌入式 NAS 系统,使用的是 定制化、精简版 Linux,不使用 systemd
| 特性 | 说明 |
|---|---|
| 内核 | Linux 5.10.60-qnap |
| Init 系统 | 不是 systemd,而是 QNAP 自研的 init 系统(类似 SysVinit) |
| 包管理 | 无 apt/yum,但支持 ipkg 或 opkg(第三方) |
/etc/os-release |
不存在(系统高度定制) |
| 服务管理 | 使用 /etc/init.d/ 脚本 + QNAP 特有机制 |
2.1创建启停脚本
# 创建启停脚本 /etc/init.d/frpc
sudo vim /etc/init.d/frpc
# 赋予可执行权限
sudo chmod +x /etc/init.d/frpc
# 确保 frpc 有执行权限
sudo chmod +x /share/homes/xlqnas/frp/frpc
/etc/init.d/frpc脚本内容如下:
#!/bin/sh
# QNAP 启动脚本:frpc
# 放在 /etc/init.d/frpc
# 使用: /etc/init.d/frpc {start|stop|restart|status}
# 日志查看 tail -f /share/homes/xlqnas/.frpc/frpc.log
FRPC="/share/homes/xlqnas/frp/frpc" # 确保这是你 frpc 的实际路径
CONFIG="/share/homes/xlqnas/frp/frpc.toml" # 配置文件路径
PIDFILE="/var/run/frpc.pid"
LOGFILE="/share/homes/xlqnas/.frpc/frpc.log" # 日志路径 需要提前创建目录 -> mkdir -p /share/homes/xlqnas/.frpc
# 检查程序是否存在
[ -x "$FRPC" ] || exit 1
# 启动函数
start() {
if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE") 2>/dev/null; then
echo "frpc is already running."
return 1
fi
echo "Starting frpc..."
# 后台启动FRP客户端并将所有输出重定向到日志文件
"$FRPC" -c "$CONFIG" > "$LOGFILE" 2>&1 &
echo $! > "$PIDFILE"
echo "frpc started."
}
# 停止函数
stop() {
if [ -f "$PIDFILE" ]; then
echo "Stopping frpc..."
kill $(cat "$PIDFILE") && rm -f "$PIDFILE"
echo "frpc stopped."
else
echo "frpc is not running."
fi
}
# 重启
restart() {
stop
sleep 1
start
}
# 查看状态
status() {
if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE") 2>/dev/null; then
echo "frpc is running (PID: $(cat $PIDFILE))"
else
echo "frpc is not running"
fi
}
# 主逻辑
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
# 启动
/etc/init.d/frpc start
# 查看状态
/etc/init.d/frpc status
# 停止
/etc/init.d/frpc stop
# 重启
/etc/init.d/frpc restart
2.2设置QNAP开机自启
# 创建 rc.local 文件并添加以下内容
sudo vim /etc/config/rc.local
# 添加后赋予可执行权限
chmod +x /etc/config/rc.local
#!/bin/sh
# 开机自动启动 frpc
if [ -x /etc/init.d/frpc ]; then
/etc/init.d/frpc start
fi
# 其他开机任务可继续添加
保存后,重启系统,frpc 会自动启动。
注:QNAP 系统更新可能清除
/etc/init.d/或rc.local
3.NAS数据库
-- 数据库基础信息
SELECT
@@basedir AS '安装目录',
@@datadir AS '数据目录',
@@tmpdir AS '临时目录',
@@plugin_dir AS '插件目录',
@@innodb_data_home_dir AS 'InnoDB数据目录',
@@innodb_log_group_home_dir AS 'InnoDB日志目录';
-- ini配置文件
cd 安装目录(/share/ZFS530_DATA/.qpkg/MariaDB10/)
vim ./etc/mariadb.conf
3.1时区设置
# 编辑 MariaDB 配置文件
sudo nano /share/ZFS530_DATA/.qpkg/MariaDB10/etc/my.cnf
# 或者
sudo nano /share/ZFS530_DATA/.qpkg/MariaDB10/etc/mariadb.conf
# 在 [mysqld] 段落下添加
[mysqld]
default-time-zone = '+08:00'
# 重启 MariaDB 服务
sudo /etc/init.d/mariadb10.sh stop
sudo /etc/init.d/mariadb10.sh start
# 查看 MariaDB 进程
ps aux | grep mariadb
3.2连接异常
[xlqnas@NAS7D955B ~]$ cd /share/ZFS530_DATA/.qpkg/MariaDB10/bin
[xlqnas@NAS7D955B bin]$ ./mysql -h 127.0.0.1 -P 3307 -uroot -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
# 这个错误表示 root 密码不正确 或者 root 用户没有本地访问权限。
ALTER USER 'root'@'localhost' IDENTIFIED BY '你的新密码';
> 1396 - Operation ALTER USER failed for 'root'@'localhost'
# 说明 MySQL 中没有 root@localhost 这个用户或者该用户已被删除或重命名
# 重新创建 root@localhost 用户
CREATE USER 'root'@'localhost' IDENTIFIED BY '你的新密码';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;