menu Chancel's blog
rss_feed
Chancel's blog
有善始者实繁,能克终者盖寡。

R2S刷入Armbian指南

作者:Chancel Yang, 创建:2024-04-21, 字数:18521, 已阅:334, 最后更新:2024-07-14

1. R2S

R2S 是一台优秀的迷你Arm服务器,其功耗低、双千兆以及价格低的优势,让这个设备非常流行

大部分R2S的教程都是刷入 openwrt 为主,这是实现透明代理网关比较简单的方案

除了 openwrt 外,R2S 其实还支持许多第三方系统,例如原生的 Linux 系统 Armbian

Armbian 可以完美地实现透明代理网关,设置起来不像openwrt一样,在Web界面上又繁琐又复杂,还经常找不到设置选项在哪里

使用 R2S + Armbian 来实现类openwrt的效果,其思路与之前的文章Linux透明网关思路一致

本文可以看成是R2S版的透明网关实现,其网络拓补图如下:

在上图中,我省略了光猫的部分,R2S将取代原来路由器的位置,2个千兆接口分别接入路由器的 WAN口 和光猫 拨号LAN口

R2S 将负责宽带拨号以及网络转发、网络分流的功能,这一点与openwrt版的R2S是一模一样的

下面将一步一步地实现拨号、DNS解析以及针对不同IP分别处理直连与科学代理

2. Armbian

Armbian是一个基于Linux的操作系统发行版,专门为ARM架构的单板计算机(如树莓派、Orange Pi等)设计和优化

这当中也包括了R2S,可以从Armbian的官网上下载得到属于R2S的Armbian系统镜像

2.1. 系统安装

R2S的官方镜像地址

下载后的系统镜像是一个 .xz 文件,无需解压 .xz ,直接将镜像写入到内存卡上插入 R2S 即可开机

  • Linux可以使用dd直接写入
  • Windows推荐使用Rufus写入

写入内存卡后,将内存卡插入R2S中,从路由器的 LAN口 连接网线到 R2S 的 LAN口

再接入电源和网线,并观察 LAN 灯是否亮起

如亮起,说明已连接到路由器下,登录到路由器后台,查看R2S被分配到的IP,之后使用SSH远程登录

  • 默认账户:root
  • 默认密码:1234

登录后会提示你进行初始化设置,包括ROOT账户密码以及一个具备管理员权限的账户

2.2. 系统设置

如果访问外网不畅通,可以将 Armbian 的源更换到清华源

安装要用的一些必要软件以及我的一些常用软件

Bash
# 更新软件包
apt update -y
# 更新系统
apt upgrade -y
# 安装必要软件
apt install -y supervisor gcc make iproute2 ipset pppoeconf vim wget git curl unzip dnsutils net-tools tree
# 安装我常用的软件(可选)
apt install -y btop proxychains openssl

此外,Armbian也支持sudo权限管理,如果有用户设置的需求,请自行编辑sudo文件进行权限分配,以下默认采用Root用户进行操作

2.3. 宽带拨号

在初始化成功后,编辑:/etc/netplan/armbian-default.yaml

YAML
network:
  version: 2
  renderer: NetworkManager
  ethernets:
    lan0: # 请确保你的LAN口名称是lan0
      dhcp4: no
      addresses: [192.168.1.1/24]
    eth0: # 请确保你的WAN口名称是eth0
      dhcp4: yes
      nameservers:
        addresses: [114.114.114.114]

编辑完成后,拔除网线,将路由器的 WAN口 接入 R2S 的 LAN口 ,将R2S的 WAN口 接入光猫的拨号口,将路由器设置为:

  • 静态IP:192.168.2.1
  • 静态网关(R2S的IP):192.168.1.1
  • 静态DNS服务(R2S的IP):192.168.1.1

接着使用ssh会话连接到 192.168.1.1 ,即你的R2S,再进行宽带拨号

Bash
pppoeconf

根据提示填入宽带帐号密码即可

再编辑:/etc/sysctl.conf

Bash
...
# 允许IPV4的流量转发
net.ipv4.ip_forward=1

并更新支持IP转发的设置

Bash
sysctl -p

然后添加临时转发规则方便进行测试

Bash
iptables -t nat -I POSTROUTING -j MASQUERADE

在局域网内,使用任意设备通过 ping 114.114.114.114 确认网络是否畅通

如果没问题,这里就已经实现了 R2S 拨号并转发网络数据

3. 透明代理网关

网络透明代理(Transparent Proxy)是一种网络代理的方式,在代理服务器和用户之间进行中间层的数据传输

对用户来说,它是透明的,用户无需进行任何额外的配置,这种代理不用在每一个设备上安装代理软件

对于一些游戏机、特定系统的设备来说很友好

3.1. 透明代理(Gost)

代理我使用的是 gost,服务端的部分可以使用商业代理或者自建服务器,这里假设代理协议是 ss

下载gost:

下载到 /root/gost/ 中,解压后目录如下

Bash
$ tree                                                      
.
├── gost
├── gost_3.0.0-rc8_linux_arm64.tar.gz
├── LICENSE
├── README_en.md
└── README.md

0 directories, 5 files

编辑:/root/gost/config.yaml

YAML
services:
- name: "1080-red" 
  addr: :1080
  handler:
    chain: chain-0
    type: red
  listener:
    type: red
- name: "1080-dns"
  addr: :1080
  handler:
    chain: chain-0
    type: dns
  listener:
    type: dns
    metadata:
      mode: udp
  forwarder:
    nodes:
      - name: Google-1
        addr: tls://8.8.8.8:853
      - name: Google-2
        addr: tls://8.8.4.4:853

chains:
- name: chain-0
  hops:
  - name: hop-0
    nodes:
    - name: "1.2.3.4" 
      addr: "1.2.3.4:48888" # ss协议的地址和端口
      connector:
        type: ss
        auth:
          username: chacha20-ietf-poly1305 # ss协议加密方式
          password: my-passwd # ss协议密码

根据你的 ss 协议,自行修改地址、端口、加密方式、密码,然后运行gost服务进行测试

Bash
/root/gost/gost -C /root/gost/config.yml

运行没有错误输出后,可以使用 supervisor 配置为后台进程

编辑:/etc/supervisor/conf.d/gost.conf

TEXT
[program:gost]
command=/root/gost/gost -C /root/gost/config.yaml
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
stdout_logfile_maxbytes=20MB
stdout_capture_maxbytes=1MB
user=root

更新supervisor运行,并检查运行状态

Bash
supervisorctl update
supervisorctl status

3.2. DNS解析(Overture)

Overture 是一个开源的 DNS 加速器和广告过滤器。它旨在提供更快的 DNS 查询响应速度,并屏蔽广告和恶意网站

稍加配置 Overture 也可以解决 DNS 污染

overture仓库地址:

由于 R2S 的 Armbian 自带DNS服务 systemd-resolved.service ,需要先将其禁用

Bash
systemctl stop systemd-resolved.service
systemctl disable systemd-resolved.service

在禁用掉自带的DNS服务后,下载后(V1.8版本)到 /root/overture 中解压,目录输出如下:

Bash
$ tree
.
├── config.yml
├── domain_alternative_sample
├── domain_primary_sample
├── domain_ttl_sample
├── hosts_sample
├── ip_network_alternative_sample
├── ip_network_primary_sample
├── overture-linux-arm64
└── overture-linux-arm64.zip

0 directories, 9 files

在运行 Overture 之前,先查找运营商指定的DNS服务地址

Bash
cat /etc/ppp/resolv.conf

服务商的DNS服务地址有CDN加速,公共DNS在访问时无法享受CDN加速

接着编辑:/root/overture/config.yml

YAML
bindAddress: :53
debugHTTPAddress: :55555
dohEnabled: false
primaryDNS:
  # 服务商的DNS服务地址,这里填的是 114.114.114.114 的公共DNS服务
  - name: domestic_dns
    address: 114.114.114.114:53
    protocol: udp
    socks5Address: 
    timeout: 3
    ednsClientSubnet:
      policy: disable
      externalIP:
      noCookie: true
onlyPrimaryDNS: false
alternativeDNS:
  # 国外DNS服务(在Gost中配置为Google)
  - name: foreign_dns
    address: 127.0.0.1:1080
    # 此处UDP对应GOST中的`mode`参数值,可选`tcp`、`udp`
    protocol: udp
    socks5Address:
    timeout: 6
    ednsClientSubnet:
      policy: disable
      externalIP:
      noCookie: true
ipv6UseAlternativeDNS: false
alternativeDNSConcurrent: false
whenPrimaryDNSAnswerNoneUse: primaryDNS
# 通过文件中的 IP 网络段来决定哪些 IP 地址的请求应该被定向到特定的 DNS 服务器
ipNetworkFile:
  # 符合 `china_ip_list.txt` 中的IP则优先使用 `primary` DNS服务的结果
  primary: /root/china_ip_list.txt
  alternative: /root/overture/ip_network_alternative_sample
# 通过文件中的域名决定哪些 IP 地址的请求应该被定向到特定的 DNS 服务器
domainFile: 
  primary: /root/overture/domain_primary_sample
  # 符合 `gfw_all_domain.txt` 中的域名则优先使用 `alternative` DNS服务的结果
  alternative: /root/gfw_all_domain.txt
  matcher: full-map
hostsFile:
  hostsFile: /root/overture/hosts
  finder: full-map
minimumTTL: 3600
domainTTLFile: /root/overture/domain_ttl_sample
# 缓存的结果数量
cacheSize: 10240
cacheRedisUrl:
cacheRedisConnectionPoolSize:
rejectQType:
  - 255

配置中重要的部分已添加了注释,在配置中使用到的1个国内IP文件与国外GFW域名名单:

  • /root/china_ip_list.txt
  • /root/gfw_all_domain.txt

2个文件的来源:

由于这两个文件都是需要定期更新,所以写一个脚本来实现

编辑: /root/update_china_and_gfw.sh

Bash
#/bin/bash
#author:Chancel.Yang
#date:2023/09/21

wget https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt
curl https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt | base64 -d | sort -u | sed '/^$\|@@/d'| sed 's#!.\+##; s#|##g; s#@##g; s#http:\/\/##; s#https:\/\/##;' | sed '/\*/d; /apple\.com/d; /sina\.cn/d; /sina\.com\.cn/d; /baidu\.com/d; /qq\.com/d' | sed '/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/d' | grep '^[0-9a-zA-Z\.-]\+$' | grep '\.' | sed 's#^\.\+##' | sort -u > temp_gfwlist.txt
curl https://raw.githubusercontent.com/hq450/fancyss/master/rules/gfwlist.conf | sed 's/ipset=\/\.//g; s/\/gfwlist//g; /^server/d' > temp_koolshare.txt
cat temp_gfwlist.txt temp_koolshare.txt | sort -u > gfw_all_domain.txt
rm -f temp_gfwlist.txt temp_koolshare.txt

/root 下执行该脚本会产生 china_ip_list.txtgfw_all_domain.txt 2个文件,如下:

Bash
$ tree -L 1
.
├── china_ip_list.txt
├── gfw_all_domain.txt
├── update_china_and_gfw.sh
├── iptables.sh
└── overture

1 directory, 4 files

运行overture

Bash
overture-linux-arm64 -c config.yaml

使用 dig 程序来验证是否能够顺利进行DNS解析

Bash
$ dig www.github.com @127.0.0.1

; <<>> DiG 9.18.4 <<>> @127.0.0.1 www.github.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8772
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;www.github.com.                        IN      A

;; ANSWER SECTION:
www.github.com.         1552    IN      CNAME   github.com.
github.com.             60      IN      A       192.30.255.113

;; Query time: 243 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Tue Jul 26 18:46:44 CST 2022
;; MSG SIZE  rcvd: 107

运行没有错误输出后,可以使用 supervisor 配置为后台进程

编辑:/etc/supervisor.d/overture.conf

TEXT
[program:overture]
command=/root/overture/overture-linux-arm64 -c /root/overture/config.yaml
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
stdout_logfile_maxbytes=20MB
stdout_capture_maxbytes=1MB
user=root

更新supervisor运行,并检查状态

Bash
supervisorctl update
supervisorctl status

3.3. 网络分流(iptables)

在完成 gost 与 overture 设置后,需要将进入 R2S 的流量进行分流

分流规则为:

  • 国内IP直连
  • 国外IP转发

编辑:/root/iptables.sh

Bash
#/bin/bash
#date:2023/09/21

/usr/sbin/ipset -N china hash:net

# china_ip_list.txt文件在overture中已经下载
for i in $(cat /root/china_ip_list.txt ); 
do
    /usr/sbin/ipset -A china $i; 
done

# 创建一个NAT规则集`SSNAT`
/sbin/iptables -t nat -N SSNAT
# 忽略国内IP
/sbin/iptables -t nat -A SSNAT -p all -m set --match-set china dst -j RETURN
# 忽略局域网IP
/sbin/iptables -t nat -A SSNAT -d 0.0.0.0/8 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 10.0.0.0/8 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 127.0.0.0/8 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 169.254.0.0/16 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 172.16.0.0/12 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 192.168.0.0/16 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 224.0.0.0/4 -j RETURN

# 将剩下IP段(国外)的流量全部转发到gost的透明代理网口1080中
/sbin/iptables -t nat -A SSNAT -p tcp -j REDIRECT --to-port 1080

# 最后将所有进入R2S的数据包转入`SSNAT`规则集合中
/sbin/iptables -t nat -A PREROUTING -p tcp -j SSNAT

# 将出站数据包的源地址进行NAT避免被防火墙拦截
/sbin/iptables -t nat -I POSTROUTING -j MASQUERADE

请再次检查你的 /root 目录,文件应如下:

Bash
$ tree -L 1
.
├── update_china_and_gfw.sh
├── china_ip_list.txt
├── gfw_all_domain.txt
├── iptables.sh
└── overture
├── gost

2 directory, 4 files

然后借助 crontab 设置脚本开机自动执行

Bash
crontab -e

# 在crontab界面中添加开机运行iptables.sh脚本
...
@reboot /bin/sh /root/iptables.sh

设置完毕后,重启R2S

3.4. 网络测试

在重启后,打开R2S的SSH会话,查看iptables的nat表,参考如下:

Bash
$ iptables -L -n -v -t nat 
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
 5371  341K SSNAT      tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
10260 1026K MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain SSNAT (1 references)
 pkts bytes target     prot opt in     out     source               destination         
 2530  171K RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set china dst
    0     0 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/8           
    3   120 RETURN     all  --  *      *       0.0.0.0/0            10.0.0.0/8          
    0     0 RETURN     all  --  *      *       0.0.0.0/0            127.0.0.0/8         
    0     0 RETURN     all  --  *      *       0.0.0.0/0            169.254.0.0/16      
    0     0 RETURN     all  --  *      *       0.0.0.0/0            172.16.0.0/12       
  234 14040 RETURN     all  --  *      *       0.0.0.0/0            192.168.0.0/16      
    0     0 RETURN     all  --  *      *       0.0.0.0/0            224.0.0.0/4         
 2604  156K REDIRECT   tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            redir ports 1080
    0     0 REDIRECT   udp  --  *      *       0.0.0.0/0            0.0.0.0/0            redir ports 1080
    0     0 REDIRECT   icmp --  *      *       0.0.0.0/0            0.0.0.0/0            redir ports 1080

再检查gost与overture的运行日志是否有异常

  • /var/log/supervisor/gost.log
  • /var/log/supervisor/overture.log

最后,使用任意连入 WI-FI 的任意设备访问下 google/bilibili 观察下国内外加载速度,验证是否成功分流

4. DHCP服务

如果路由器支持有线中继,那么也可以让 R2S 充当DHCP服务器,从而实现更强的控制效果,例如:

  • 有线中继后,192.168.2.0/24段将舍弃,由 R2S 负责分配IP,动态分配192.168.1.128到192.168.1.255之间的IP给所有设备
  • IP段在192.168.1.128到192.168.1.255之间的IP则不经过透明代理
  • IP段在192.168.1.1到192.168.1.127之间的IP则经过透明代理

4.1. 动态IP分配(isc-dhcp-server)

安装 DHCP 分配服务

Bash
apt update
apt install isc-dhcp-server

编辑:/etc/dhcp/dhcpd.conf

TEXT
...

# 默认的租约时间12小时
default-lease-time 43200;
# 允许的最大租约时间7天
max-lease-time 604800;

...

# 局域网设备将自动分配 192.168.1.128 到 192.168.1.254 的IP段
subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.128 192.168.1.254;
  option routers 192.168.1.1;
  option domain-name-servers 192.168.1.1;
}

编辑:/etc/default/isc-dhcp-server

TEXT
...
# 限定 DHCP 服务作用的接口为 `lan0`
INTERFACESv4="lan0"

启动和开机自启 isc-dhcp-server 服务

Bash
systemctl enable --now isc-dhcp-server

最后开启路由器的有线中继模式,开启成功后,可以在 R2S 中查看当前已分配的IP列表:

Bash
$ dhcp-lease-list
Reading leases from /var/lib/dhcp/dhcpd.leases
MAC                IP              hostname       valid until         manufacturer        
===============================================================================================
40:31:3c:d9:ef:65  192.168.11.171  chunmi-cooker- 2024-07-09 08:43:22 XIAOMI Electronics,CO.,LTD
64:82:14:b4:f6:6c  192.168.11.165  NarwalRobotics 2024-07-09 08:43:49 FN-LINK TECHNOLOGY Ltd.
78:8b:2a:9d:e9:a1  192.168.11.166  chuangmi.camer 2024-07-09 08:44:09 Zhen Shi Information Technology (Shanghai) Co., Ltd.
7c:c2:94:23:e0:5b  192.168.11.168  zhimi-airpurif 2024-07-09 08:40:16 Beijing Xiaomi Mobile Software Co., Ltd
94:f8:27:b0:63:b1  192.168.11.157  chuangmi_camer 2024-07-09 08:44:05 Shanghai Imilab Technology Co.Ltd
cc:b5:d1:7c:26:cb  192.168.11.164  midjd6-fridge- 2024-07-09 08:42:18 Beijing Xiaomi Mobile Software Co., Ltd
d4:f0:ea:69:a2:0c  192.168.11.167  philips-light- 2024-07-09 08:42:36 Beijing Xiaomi Mobile Software Co., Ltd
d4:f0:ea:6a:ae:7d  192.168.11.160  yeelink-light- 2024-07-09 08:42:09 Beijing Xiaomi Mobile Software Co., Ltd
d4:f0:ea:85:10:5a  192.168.11.162  yeelink-light- 2024-07-09 08:42:08 Beijing Xiaomi Mobile Software Co., Ltd
d4:f0:ea:85:19:30  192.168.11.163  yeelink-light- 2024-07-09 08:42:13 Beijing Xiaomi Mobile Software Co., Ltd
dc:ed:83:61:9b:fd  192.168.11.172  lumi-acpartner 2024-07-09 08:43:34 Beijing Xiaomi Mobile Software Co., Ltd
dc:ed:83:ec:17:3c  192.168.11.170  lumi-acpartner 2024-07-09 08:43:52 Beijing Xiaomi Mobile Software Co., Ltd

如果分配IP出现问题,可以通过 journalctl 来查看 DHCP 服务日志排查问题:

Bash
journalctl -xeu isc-dhcp-server.service -f

4.2. 动态IP忽略透明代理(iptables)

在配置DHCP的IP分配后,局域网内的设备将默认被分配到 192.168.1.128 到 192.168.1.254 之间

结合之前 iptables 脚本就可以实现对动态IP不进行透明代理的效果

编辑:/root/iptables.sh

Bash
#/bin/bash
#date:2023/09/21

/usr/sbin/ipset -N china hash:net

# china_ip_list.txt文件在overture中已经下载
for i in $(cat /root/china_ip_list.txt ); 
do
    /usr/sbin/ipset -A china $i; 
done

# 创建一个NAT规则集`SSNAT`
/sbin/iptables -t nat -N SSNAT
# 国内IP
/sbin/iptables -t nat -A SSNAT -p all -m set --match-set china dst -j RETURN
# 忽略局域网IP
/sbin/iptables -t nat -A SSNAT -d 0.0.0.0/8 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 10.0.0.0/8 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 127.0.0.0/8 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 169.254.0.0/16 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 172.16.0.0/12 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 192.168.0.0/16 -j RETURN
/sbin/iptables -t nat -A SSNAT -d 224.0.0.0/4 -j RETURN

# 忽略192.168.1.128到192.168.1.255之间的IP
/sbin/iptables -t nat -A SSNAT -s 192.168.1.128/25 -j RETURN

# 将剩下IP段(国外)的流量全部转发到gost的透明代理网口1080中
/sbin/iptables -t nat -A SSNAT -p tcp -j REDIRECT --to-port 1080

# 最后将所有进入R2S的数据包转入`SSNAT`规则集合中
/sbin/iptables -t nat -A PREROUTING -p tcp -j SSNAT

# 将出站数据包的源地址进行NAT避免被防火墙拦截
/sbin/iptables -t nat -I POSTROUTING -j MASQUERADE

对于需要使用透明代理的设备,则可以通过 DHCP 服务来指定分配到 192.168.1.2 至 192.168.1.127 之间的IP,这些IP将被透明代理处理

编辑:/etc/dhcp/dhcpd.conf

TEXT
...

# 默认的租约时间12小时
default-lease-time 43200;
# 允许的最大租约时间7天
max-lease-time 604800;

...

# 局域网设备将自动分配 192.168.1.128 到 192.168.1.254 的IP段
subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.128 192.168.1.254;
  option routers 192.168.1.1;
  option domain-name-servers 192.168.1.1;

  # 固定某个设备的IP为192.168.1.2
  host My-Windows-PC {
        hardware ethernet 00:a0:ae:aa:a0:ac;
        fixed-address 192.168.1.2;
    }
}

在编辑成功后,如果发现网络有异常或者没有走透明代理,可以使用 watch 结合 iptables 来监控数据包走向来判断问题:

Bash
watch -n 1 iptables -L -n -v -t nat

5. 尾语

以上内容较为复杂,还需耐心检查每一步的日志输出


[[replyMessage== null?"发表评论":"发表评论 @ " + replyMessage.m_author]]

account_circle
email
web_asset
textsms

评论列表([[messageResponse.total]])

还没有可以显示的留言...
gravatar
[[messageItem.m_author]] [[messageItem.m_author]]
[[messageItem.create_time]]
[[getEnviron(messageItem.m_environ)]]
[[subMessage.m_author]] [[subMessage.m_author]] @ [[subMessage.parent_message.m_author]] [[subMessage.parent_message.m_author]]
[[subMessage.create_time]]
[[getEnviron(messageItem.m_environ)]]