一、远程桌面概述

windows自带的远程桌面(remote destop)服务能够让用户便利的远程控制电脑。因为是微软的系统服务,与市面上的一些第三方远程桌面工具如teamviewer、向日葵和rustdesk等相比,具有独特的使用优势。其基本要求如下:

  • 远程电脑Windows 10/11专业版及以上
  • 远程电脑防火墙开放远程控制端口3389
  • 本地电脑可以连同远程电脑,即在相同局域网内,且知道远程电脑IP
    用户可以在系统设置中开启远程桌面功能。同时用户可以通过下列命令修改远程桌面默认端口,例如使用3390。
    1
    2
    3
    4
    5
    6
    # 修改远程桌面端口
    Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -name "PortNumber" -Value 3390;
    # 删除旧的进站规则
    Remove-NetFirewallRule -DisplayName 'RDPPORT';
    # 修改防火墙进站规则给新端口放行
    New-NetFirewallRule -DisplayName 'RDPPORT' -Profile 'Any' -Direction Inbound -Action Allow -Protocol TCP -LocalPort 3390 -RemotePort Any -Enabled True;
    然后就可以通过内置应用“远程桌面连接”来连接目标电脑。其他RDP细节问题本文不做介绍,本文目的在于介绍内网穿透配合RDP实现跨局域网访问。

二、内网穿透

本文的内网穿透基于自己拥有公网IP的服务器,如若需要公用服务器,请走其他穿透途径。为了阅读方便,坐下述代号约定:

  • 作为中介的服务器:S
  • 待被访问的远程电脑:R
  • 用来访问的本地电脑:L

2.1 SSH本地端口转发

当S能够直接访问到R,而L不能直接访问到R时,可以登录S,建立S->R的SSH本地端口转发,实现内网穿透

1
ssh -f -g -N -L S的端口3389:R的IP:R的远程桌面端口3389 localhost

2.2 SSH远程端口转发

当R能访问S而S不能访问R时,可以由R发起SSH远程端口转发.

1
ssh -f -g -N -R S的端口3389:R的IP:R的远程桌面端口3389 <S的SSH账号>@<S的IP>

2.3 基于nps构建内网穿透

SSH转发的隧道不稳定,且没有自动重连机制,nps是一款Go语言开发的开源内网穿透工具ehang-io/nps。按照其安装教程分别在S上安装启用服务端nps和在R上安装启用客户端npc。其基本步骤如下:

  • 在S在下载安装nps,sudo nps install
  • 修改S上nps的配置,主要是修改web管理端口8080,穿透通讯端口8024,web管理的账号密码等。注意端口需要保证不被其他程序占用。
  • 在S上启动nps服务,sudo nps start
  • 在服务器防火墙上放行上述端口,具体放行方法自行咨询服务器供应商。
  • 登录web管理页面http://<S的域名/IP>:8080/,新建客户端,复制验证密钥
  • 在R上下载npc
  • 修改配置文件conf/npc.conf,设置server_addrvkey,将不必要的隧道类型注释掉,只保留tcp,tcp端口为你的RDP端口,否则会遇到相关issue的bug,如下。
  • 将其安装为系统服务npc install并启动npc start
  • 此时可以通过远程电脑连接了。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    [common]
    server_addr=S的IP/域名:8024
    conn_type=tcp
    vkey=复制的验证密钥
    auto_reconnection=true
    max_conn=1000
    flow_limit=1000
    rate_limit=1000
    basic_username=11
    basic_password=3
    web_username=user
    web_password=1234
    crypt=true
    compress=true
    #pprof_addr=0.0.0.0:9999
    disconnect_timeout=60

    [health_check_test1]
    health_check_timeout=1
    health_check_max_failed=3
    health_check_interval=1
    health_http_url=/
    health_check_type=http
    health_check_target=127.0.0.1:8083,127.0.0.1:8082

    [health_check_test2]
    health_check_timeout=1
    health_check_max_failed=3
    health_check_interval=1
    health_check_type=tcp
    health_check_target=127.0.0.1:8083,127.0.0.1:8082

    # [web]
    # host=c.o.com
    # target_addr=127.0.0.1:8083,127.0.0.1:8082

    [tcp]
    mode=tcp
    target_addr=127.0.0.1:3389
    server_port=3389

    # [socks5]
    # mode=socks5
    # server_port=19009
    # multi_account=multi_account.conf

    # [file]
    # mode=file
    # server_port=19008
    # local_path=/Users/liuhe/Downloads
    # strip_pre=/web/

    # [http]
    # mode=httpProxy
    # server_port=19004

    # [udp]
    # mode=udp
    # server_port=12253
    # target_addr=114.114.114.114:53

    # [ssh_secret]
    # mode=secret
    # password=ssh2
    # target_addr=123.206.77.88:22

    # [ssh_p2p]
    # mode=p2p
    # password=ssh3

    # [secret_ssh]
    # local_port=2001
    # password=ssh2

    # [p2p_ssh]
    # local_port=2002
    # password=ssh3
    # target_addr=123.206.77.88:22

三、问题解决

  1. 微软账号登录RDP

微软账号不同于本地账号,其密钥不会自动缓存在本地而在远程连接时报错凭据问题。可以通过管理员身份执行下列命令缓存密码。

1
runas /u:微软账号邮箱 cmd.exe

  1. invalid syntax

该bug应该是nps项目开发对配置文件管理异常,相关解决方案如前,即注释掉多余的不用的部分。

  1. Linux下npc安装到系统服务失败

在Linux安装npc客户端某些版本时,无法成功安装到系统服务,issue

1
2
3
sudo npc install
sudo npc start
sudo systemctl status Npc # 报错找不到conf/npc.conf

这时候需要修改/etc/systemd/system/Npc.service文件,把指定config参数
1
ExecStart=/root/npc/v0.26.10/npc "-config=/root/npc/v0.26.10/conf/npc.conf"

最后执行下列命令重新加载服务即可。
1
2
sudo systemctl daemon-reload
sudo systemctl enable Npc

  1. Windows下nps服务几天后失效

这个问题同相关issue
是因为Windows安全中心定期扫描将nps作为风险隔离,
可以通过“病毒和威胁防护>管理设置>排除项”将nps所在文件夹排除即可。