侧边栏壁纸
博主头像
翠南山 博主等级

行动起来,活在当下

  • 累计撰写 11 篇文章
  • 累计创建 6 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Docker搭建FRP服务使能远程ssh访问

居不正
2023-11-16 / 0 评论 / 0 点赞 / 24 阅读 / 0 字

背景

最近,由于有远程访问局域网电脑的需要,于是想着搭建一个frp服务方便自己在家里访问公司电脑,或者在公司访问家里的电脑。这里记录一下整体的过程,一方面作为记录,另外一方面,在搭建的过程中配到部分问题,这里把解决方式记录下来,也可以给碰到相同问题的其他人一些帮助。

构想

个人搭建服务一般都是尽量减少暴露端口,因此,个人的基本设置基本上都是:

基本上就是把HTTP服务都藏在Nginx后面,然后将其他服务都加入到NginxProxyManager的网络中,保证HTTP服务都通过Nginx反向代理。

因此,在搭建frp服务的时候,个人坚持的是同样的原则,尽可能减少端口的暴露。

动手

frps配置

首先,在服务器上配置frps,下面是我frps的配置和docker-compose文件。

  • docker-compose.yml
version: '3.3'
services:
  frps:
    restart: always
    volumes:
      - ./etc/frp/frps.toml:/etc/frp/frps.toml
    container_name: frps
    image: snowdreamtech/frps
    networks:
      - nginxproxymanager_default
    ports:
      - 7000:7000
      - 6001:6001
      - 6002:6002

networks:
  nginxproxymanager_default:
    external: true
  • frps.toml
bindPort = 7000
token = "XXXXXXXXX"

# 日志配置
log.level = "trace"

# dashboard
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "ADMIN"
webServer.password = "ADMIN-PASSWORD"

整体来说,配置非常简单。不过,这里需要对Dashboard配置进行一些简单的说明。

Dashboard说明

一开始,我的配置文件是下面这样:

```toml
bindPort = 7000

# dashboard
webServer.port = 7500
webServer.user = "ADMIN"
webServer.password = "ADMIN-PASSWORD"

整体的内容同官网介绍的类似:
image.png
但是,个人发现一个问题:无论在nginx proxy manager中如何配置,都无法访问dashboard。后来排查后发现,如果不设置的话,其默认值为127.0.0.1,属于本地回环地址。其他docker访问其网络的时候,由于对于该容器来说属于外部网络,因此无法访问本地。因此,只需要修改其值为0.0.0.0后,其可以监听外部网络的数据后,既可以正常访问。

frpc配置

在个人电脑端,同样使用docker配置,个人的docker-compose文件和配置如下:

  • docker-compose.yml
version: '3'
services:
  frpc:
    restart: always
    image: snowdreamtech/frpc
    container_name: frpc
    volumes:
      - ./etc/frp/frpc.toml:/etc/frp/frpc.toml
    #network_mode: host
    ports:
      - 7000:7000
    networks:
      - npm_default
    extra_hosts:
      - "host.docker.internal:host-gateway"

networks:
  npm_default:
    external: true
  • frpc.toml
serverAddr = "SERVER-ADDRESS" # 服务器地址
serverPort = 7000 # 和服务器一样的端口
token = "TOKEN-THE-SAME-WITH-SERVER"

[[proxies]]
name = "ssh-home"
type = "tcp"
localIP = "host.docker.internal"
localPort = 22
remotePort = 6002

对于frpc的配置来说,主要有两个地方需要说明,这也是我排查了半天才找到原因的地方。

  1. extra_hosts这一句的作用是将docker网络的网关地址加入到host文件中,后面就可以在容器内使用host.docker.internal来访问网关;
  2. localIP的设定之所以是网关是因为需要将网络信息转发到主机的ssh中,这样才能实现远程的访问。

在这里简单说一下我碰到的问题和排查过程,有兴趣就继续看,没兴趣就可以直接跳过。

ssh无法访问问题

为了更好的说明问题,这里把具体碰到问题的表现截图放上来:
image.png
从图中来看,整体的表现就是使用ssh登录设备,报kex_exchange_identification错误。单独从输出日志来看,会这个问题发生的原因是认证失败导致的。我谷歌也好、百度也罢,找了很久的信息,并没有找到该问题的合适解决方案。

为了解决这个问题,我做了以下实验:

  1. 检查内网电脑和服务器的链接,在执行该指令的时候,服务器所显示的日志是什么?
  2. 检查执行该指令的时候,电脑上sshd的输出内容是什么?再对比本地登录sshd的输出信息是什么?然后确认问题原因。
    通过这两个部分的信息来帮助我查找和配查问题。

[!note]

整体来说,个人的思路是个人理解,frp扮演的角色应该是类似于v2ray的角色,实现的是网络的端口转发。ssh的数据包一定先发送给服务器的6002端口,再通过frps转发给frpc,再通过frpc转发给本地ssh。其整体链路如下图:

根据这个思路,把所有的日志登记都调整到输出最详细日志:

  1. 修改了frps的日志等级,因此可以看到上面的配置文件中log.level = "trace"这个信息。
  2. 修改了sshd的日志配置,修改/etc/ssh/sshd_configLogLevel DEBUG3

然后执行远程登录指令,发现:

  1. frps的输出正常,但是会遇到快速的链接被关闭;
    image.png
  2. 检查本机的sshd的日志输出,没有发现任何的日志输出

根据这两个信息,个人做出以下推断:数据链路在frpc发送给本地ssh时中断了。因此,需要调整的配置时frpc中关于ssh的配置。在做完下面的修改后,EVERYTHING IS FINE!!!

localIP = "host.docker.internal" # 原来是127.0.0.1,但ssh服务在主机上,需要通过网关访问

后记

要解决问题,要从原理上入手!

0

评论区