NAS系列 基于Clash内核的策略分流方案
本文最后更新于 160 天前,如有失效请评论区留言。

本博客由ZGOCLOUD大力赞助!如何更快地访问本站?有需要可加电报群获得更多帮助。本博客用什么VPS?创作不易,请支持苯苯!推荐购买本博客的VIP喔,10元/年即可畅享所有VIP专属内容!

前言

自2023-11-3起,Clash内核已经删库并终止维护,该项目的前景十分渺茫,不建议新人使用Clash相关流程。

本系列教程所配置的网络均为Ipv4网络,所以并不适合使用Ipv6的小伙伴。

在《NAS系列 在PVE中搭建OpenWrt虚拟机》中,我们已经搭建OpenWrt虚拟机并成功地用了起来。讲到OpenWrt,就不得不提OpenClash了。OpenClash是一个非常有名的OpenWrt插件。根据官方仓库的介绍,它是一个可运行在OpenWrt 上的Clash客户端,兼容多种网络协议,根据灵活的规则配置实现策略连接

msedge_EqY9tDxOaN

Clash其实是一个内核,它定义了一些网络连接的基本功能。OpenClash更多地是提供一个方便交互和管理的GUI,它本质上是基于Clash内核的。其它基于Clash内核的应用,比如Clash for Windows,和OpenClash并没有本质区别。

下面是一个关于普通网络Clash网络主要区别的简单示意图:

image-20230322102756887

比如访问1baidu.com,我希望让它按默认情况连接(规则1;Direct)。访问2https://ad.js,是一个和广告相关的js脚本;因为我不想看到广告,所以我希望它被阻断(规则2;Block)。访问3是单位网站,我希望它走单位提供的连接(规则3)。说到这里,如果你觉得OpenClash的功能对你的日常场景没有帮助,那么对本章内容的了解就可以到此为止了

本教程的重点并不是讲解应该如何在OpenClash的GUI里操作某些项目;而是专注于了解Clash的配置文件。我个人认为,配置文件才是认识并自定义Clash的最佳起点。我会从一个虚拟应用场景——“远程办公”——讲述Clash的策略分流是如何帮助我们较好地协调网络。

场景

假设由于某些情况,你需要在家里远程办公。办公过程就是要访问公司的某些网站,比如财务部(以caiwu.com为后缀)和销售部(以xiaoshou.com为后缀)。由于办公时可能包含一些公司的敏感信息,公司给你提供了特定协议的登陆帐号(假设Clash支持该协议)和DNS服务器,以防机密数据泄露。如果你家里的路由器使用OpenWrt系统和OpenClash插件,如何设计网络以满足该场景且不影响正常上网?

分析

一般来说,只要我们通过https连接网络,非目标网站的访客是无法解密其中的内容的(原理同ssh)。不过,基于Clash内核可以让安全性进一步提升——它可以避免DNS泄露

我们先从一般情况讲起。首先,我们在浏览器里访问caiwu.com。我们在《了解IP地址》中提到过,互联网设备之间是通过IP来互相识别的。我们的浏览器并不知道caiwu.com对应的是哪个IP,所以就会发起一条DNS请求。DNS即Domain Name Server,中文是“域名服务器”,它记录了许多“域名-IP”对,可以明确域名到IP的映射关系:

msedge_GHl7kxNl89

OpenWrt会事先指定一些DNS公共服务器,比如114.114.114.114114.114.114.114是国内移动、电信和联通通用的DNS,手机和电脑端都可以使用,解析成功率高、速度快、稳定,较为常用。不过,实际情况是,该DNS查询也可能会走很多个公共DNS服务器才能找到符合条件的记录。

由于DNS查询的过程是明文的,114.114.114.114和其它过路DNS服务器其实已经知道该DNS查询的来源IP(因为它要返回记录给你,必然要知道你的IP),这其实就是所谓的“DNS泄露”。狭义上的“DNS泄露”指保密网址(比如这里的caiwu.com)在公共服务器中进行DNS查询后导致源IP暴露。还有另外一种情况据说也是挺常见的,叫“DNS污染”,即返回了假IP(Fake-IP)——比如caiwu.com的真实IP是1.1.1.1,但返回的IP是2.2.2.2。一般而言,DNS泄露会导致安全性问题;DNS污染可能会导致网址无法正常访问。此外,DNS的加密也是DNS泄露中值得关注的重要问题。像114.114.114.114等非加密DNS服务器,DNS解析的过程中很容易被中间人拦截并返回中间人故意插入的信息(比如返回一个指向赌博广告的IP地址),这对于DNS解析的发起者来说往往是有害的,无疑也是安全上网中的“debuff”(比如该新闻)。

总之,在本场景中,由于单位提供了专属DNS服务器,所以我们要保证关于caiwu.com的DNS请求只能去请求该专属DNS服务器,这样就可以避免caiwu.com的DNS泄露。当然,也要保证一般网站(比如baidu.com)的DNS请求可以走114.114.114.114之类的DNS公共服务器,以避免专属DNS服务器的DNS解析失败(因为我们不知道这个专属DNS服务器是否保存了baidu.com的域名-IP对)。总之,我们需要设计某种规则,让DNS解析进行“分流”,不同类型的域名走不同的DNS服务器

其实这个场景看似简单,但在透明代理的情况下,对于Clash内核的用户来说不是一件容易的事。Clash有一种模式叫“redir-host”,它本身会想办法获得域名的真实IP,就不可避免地向所有DNS服务器并行进行DNS请求,所以DNS泄露是在所难免的。我也是折腾了好久,才试出一种可以在Clash内核中使用的看似完美的“曲线救国”方案。下面我们通过yaml配置文件来展示这种方案的具体细节。

示例配置文件

大家需要下载好示例配置文件(Nextcloud; Alist)。用纯文本编辑器(如NotePad++或txt阅读器)即可打开。

使用过docker-compose的小伙伴应该对yaml格式很熟悉了,Clash内核的行为基本上都可以通过yaml格式的配置文件来定义。为了方便讲解,我调整了一些参数的顺序,它们可能与实际顺序有较大的差别。下面咱们就一块块地剖析这个Clash配置文件示例。

基本信息

---
port: 7890 # HTTP(S) 代理端口
socks-port: 7891 # SOCKS5 代理端口
redir-port: 7892 # 流量转发端口
tproxy-port: 7895 # TProxy端口
mixed-port: 7893 # 混合代理端口
mode: rule # 使用rule策略

示例文件中的开头定义了一些Clash参数,比如指定哪些用途用什么端口、使用什么模式之类的。和我们的关系不大,直接略过。

TUN模式

tun: # TUN模式
  enable: true
  stack: system # 网络栈类型
  auto-route: false
  auto-detect-interface: false
  dns-hijack:
  - tcp://any:53 # 53端口向DNS服务器开放

enable: true表明使用TUN模式(Tunnel;“隧道”之意)。Clash在TUN模式下会建立一个虚拟网卡,从网络层托管连接;而所有发往互联网的流量都需要经过网络层,因此TUN模式可以比较充分地接管局域网所有设备/所有应用的互联网流量。

在PVE.OpenWrt Shell里通过ip a查看网上信息,可以发现一个叫utun的虚拟网卡:

utun: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 9000 qdisc mq state UNKNOWN group default qlen 500
    link/none
    inet 198.18.0.1/16 scope global utun
       valid_lft forever preferred_lft forever
    inet6 fe80::1b21:4d12:XXX:XXXX/64 scope link stable-privacy
       valid_lft forever preferred_lft forever

其中,网段198.18.0.1/16是用来分配假IP的,后面会提到。

我们再看看其它参数。stack: system表明使用操作系统自带的tcpip协议栈,兼容性更强、更稳定。另一个类似的协议是stack: gvisor,可以在用户空间直接解析数据,性能更好;具体内容可以参考文章《gvisor的网络栈实现-简介》。这个参数我们作简单了解就行。在实际使用中,你可以试试看哪个好用;默认是使用system

这里注意的是dns-hijack(DNS劫持)的相关参数——tcp://any:53代表接管局域网中所有IP的53端口请求。一般情况下,DNS请求就是通过53端口传递的。此时,如果你在局域网内任何一个机器访问了某网站,该网站的DNS请求会被Clash内核劫持。

DNS模块

本文的重难点内容。

dns:
  enable: true
  ipv6: false
  enhanced-mode: fake-ip # Fake-IP模式
  fake-ip-filter:
  - "+.baidu.com"
  - "+.bilibili.com"
  fake-ip-range: 198.18.0.1/16
  listen: 0.0.0.0:7874 # DNS监听端口
  nameserver:
  - 192.168.1.254:5336 # AdGuard Home 01,上游DNS服务器为公众所有。
  fallback:
  - tcp://192.168.1.254:5335 # AdGuard Home 02,上游DNS服务器为公司专用
  # https://lancellc.gitbook.io/clash/clash-config-file/dns#fallback-filter
  fallback-filter:
    geoip: true
    geoip-code: 非公司网站 # geoip=true, geoip-code=非公司网站。这样设置的结果是:非公司网站使用nameserver的DNS结果。
    domain:
    - "+.xiaoshou.com"

由于我们需要利用Clash内核对DNS请求进行分流,因此配置文件必须要包含dns模块。首先,listen: 0.0.0.0:7874表明Clash监听DNS请求的端口为7874。一般地,OpenWrt会自带一个DNS转发器;我们需要设置127.0.0.1:7874为默认且唯一的DNS转发端口,这样才可以保证所有的DNS请求被Clash顺利接管(原端口是TUN模式中约定的53端口):

msedge_85foe5uip3

关于0.0.0.0127.0.0.1的区别可见《127.0.0.1和0.0.0.0地址的区别 – 腾讯云开发者社区-腾讯云》。在路由器中,这两个地址似乎没区别?有了解的小伙伴可以评论区留言哈!

enhanced-mode: fake-ip表明使用的是Clash内核的Fake-IP模式。Fake-IP模式的主要策略是通过为请求DNS解析的域名提供一个假IP(从fake-ip-range: 198.18.0.1/16里随机选1个并保证不重复)来“骗”、来“忽悠”浏览器发出的DNS请求,从而继续后面的步骤;并且不再向其它服务器发起真正的DNS请求。

198.18.0.1/16属于CIDR地址,我们可以用IPv4 / IPv6 CIDR计算器来看看198.18.0.1/16对应的IP段:

msedge_TOYlYP0MFC

因此,198.18.0.1/16是一个非常大的网段,合计65536个IP。再结合非常短的IP有效时间和其它机制,Fake-IP模式可以保证家用环境下不同域名映射一个不同的假IP,且不发生IP重复。

下面,我们举几个例子来说明该dns策略是如何全面“照顾”我们的上网需求的。

访问caiwu.com

当我们访问caiwu.com时,浏览器给OpenWrt发送DNS请求,从而被Clash接管。由于fake-ip-filter名单里面并没有caiwu.com,因此Clash会给caiwu.com一个假IP。我们指定了一个局域网段198.18.0.1/16提供假IP,比如最终确定了caiwu.com-198.18.0.0的域名-IP对。此时DNS模块的流程已经完成。

由于我们一开始设定了Clash模式——mode: rule,因此caiwu.com-198.18.0.0将直接进入rules中进行匹配:

rules:
- "DOMAIN-SUFFIX,caiwu.com, 财务部代理"
# - "DOMAIN-SUFFIX,xiaoshou.com, 销售部代理"
- GEOIP,CN,直连
- MATCH,代理

由于caiwu.com满足第1条规则"DOMAIN-SUFFIX,caiwu.com, 财务部代理",因此走财务部代理这个代理组(proxy-groups):

proxy-groups:
- name: "财务部代理"
  type: select
    proxies:
    - "公司财务部代理1"
    - "公司财务部代理2"

因此是走公司财务部代理1公司财务部代理2节点。它们的具体信息在proxies模块中已经列举:

proxies:
- name: 公司财务部代理1
  帐号信息
- name: 公司财务部代理2
  帐号信息

此时,访问caiwu.com的请求会通过这两个节点之一完成。由于这是公司提供的网络环境,caiwu.com的DNS解析和后续访问会在公司的内部网络里完成。然后数据返回时再按原来的道路反方向回来并在浏览器本地解密,我们的浏览器就显示了我们想要的信息(这个过程实际上非常复杂,这里只是一个简化描述)。

纵观全程,访问caiwu.com的过程并不会发起公共DNS请求,而是经过Fake-IP化后直接在公司服务器里完成后续的DNS解析和数据访问。因此,该网络结构有效地防止了caiwu.com的DNS泄露。由于公司服务器必然知道自己网站(包括caiwu.com)的真实IP,因而也防止了DNS污染。

访问baidu.com

当我们访问baidu.com时,浏览器给OpenWrt发送DNS请求,从而被Clash接管。由于fake-ip-filter名单里面包含了baidu.com

fake-ip-filter:
- "+.baidu.com"
- "+.bilibili.com"

因此Clash不会给baidu.com分配假IP(此时fake-ip-range: 198.18.0.1/16自然也不会生效),而是直接向Openwrt的DNS服务器发起并行DNS请求

在本规则中,我们定义了两个DNS服务器——nameserverfallback

nameserver:
- 192.168.1.254:5336 # AdGuard Home 01,上游DNS服务器为公众所有。
fallback:
- tcp://192.168.1.254:5335 # AdGuard Home 02,上游DNS服务器为公司专用。

其中nameserver指向192.168.1.254:5336,它其实是一个AdGuard Home的Docker容器,包含上游DNS服务器(比如114.114.114.114或者其它你想要加入的公共DNS)和一些广告过滤规则。fallback是另一个AdGuard Home的Docker容器,它的上游DNS服务器则是公司专属DNS服务器。这其实就是所谓的利用“双AdGuard Home”提供差异化DNS解析服务。理论上这是一种比较消耗资源的方案,但软路由的性能一般都比较强大,因此和轻量级方案相比并没有明显的性能受限。

不管怎样,DNS解析工作已经开始了。假设baidu.comnameserver中的解析时间是tn,在fallback中的解析时间是tf。由于baidu.com是一家非常出名的公司,它的域名-IP对遍布各大DNS服务器;而fallback对应的公司专属DNS服务器则不一定会记录baidu.com的域名IP对。所以,一般来说,tn<<tf,故Clash内核会优先选择nameserver的解析结果。

当然,也可能会发生tf>tn的情况,这时就不太符合我们的预期了。没关系,我们还设计了另一层机制——fallbacke-filter——来保证解析baidu.com时Clash内核会优先选择nameserver的解析结果:

fallback-filter:
    geoip: true
    geoip-code: 非公司网站
    domain:
    - "+.xiaoshou.com"

GEOIP是一个非常著名的数据库,它记录了定期更新的IP-地理位置映射关系。我们设置了geoip=true, geoip-code=非公司网站,这样的结果是:非公司网站均优先使用nameserver的DNS结果。由于baidu.com是一家非常出名的公司,其IP已经被GEOIP数据库记录过,因此属于非公司网站。总之,通过nameserver/fallback时间差和fallbacke-filter等机制,解析baidu.com时Clash内核会优先选择nameserver的解析结果

由于baidu.com是一家非常有名的国内公司,nameserver基本上可以获得真实IP,因此避免了DNS污染。“访问baidu.com”本身是一种普通的上网行为,并不需要像保密公司网址一样保护,故不存在狭义上的DNS泄露。

完成DNS解析后走rules模块:

rules:
- "DOMAIN-SUFFIX,caiwu.com, 财务部代理"
# - "DOMAIN-SUFFIX,xiaoshou.com, 销售部代理"
- GEOIP,CN,直连
- MATCH,代理

由于并不匹配第1条规则,baidu.com继续适配规则GEOIP,CN,直连。由于baidu.com是一家非常出名的公司,其IP已经被GEOIP数据库记录过;直接根据此前已经获得的真实IP,判定baidu.com符合规则GEOIP,CN,直连。最终,使用该真实IP进行直连访问(也就是普通的方式)。

访问xiaoshou.com

当我们访问xiaoshou.com时,浏览器给OpenWrt发送DNS请求,从而被Clash接管。由于fake-ip-filter名单里面并没有xiaoshou.com,因此Clash会给xiaoshou.com一个假IP。我们指定了一个局域网段198.18.0.1/16提供假IP,比如最终确定了xiaoshou.com-198.18.0.3的域名-IP对。此时DNS模块的流程已经完成。

由于我们一开始设定了Clash模式——mode: rule,因此xiaoshou.com-198.18.0.3将直接进入rules中进行匹配:

rules:
- "DOMAIN-SUFFIX,caiwu.com, 财务部代理"
# - "DOMAIN-SUFFIX,xiaoshou.com, 销售部代理"
- GEOIP,CN,直连
- MATCH,代理

xiaoshou.com并不符合第1条规则,因此尝试适配规则GEOIP,CN,直连。由于不知道xiaoshou.com的真实IP,这里会发起并行DNS请求(通过nameserverfallback),此时xiaoshou.com会发生狭义的DNS泄露。

不过,我们设置了fallback-filter的保护机制使得xiaoshou.com的DNS请求一定可以获得真实IP——直接在domain里添加xiaoshou.com即可:

fallback-filter:
    geoip: true
    geoip-code: 非公司网站
    domain:
    - "+.xiaoshou.com"

根据Clash文档,添加到fallback-filterdomain里的域名会标记为污染域名,从而只应用fallback请求所获得的IP。由于fallback的上游DNS服务器则是公司专属的DNS服务器,因此必然可以获得xiaoshou.com的真实IP。

总之,在本策略中访问xiaoshou.com会引起狭义的DNS泄露,但可以保证xiaoshou.com正常连接。因此,正确的做法应该是去掉rules模块中第2行的注释,直接表明xiaoshou.com会走公司服务器:

rules:
- "DOMAIN-SUFFIX,caiwu.com, 财务部代理"
- "DOMAIN-SUFFIX,xiaoshou.com, 销售部代理" # 添加这个规则可以防止DNS泄露
- GEOIP,CN,直连
- MATCH,代理

这样情况就会类似于访问caiwu.com,安全性和可连接性都有保障。

访问hwb0307.com

当我们访问hwb0307.com时,浏览器给OpenWrt发送DNS请求,从而被Clash接管。由于fake-ip-filter名单里面并没有hwb0307.com,因此Clash会给hwb0307.com一个假IP。我们指定了一个局域网段198.18.0.1/16提供假IP,比如最终确定了hwb0307.com-198.18.0.1(与其它域名不相同)的域名-IP对。此时DNS模块的流程已经完成。

由于我们一开始设定了Clash模式——mode: rule,因此hwb0307.com将直接进入rules中进行匹配:

rules:
- "DOMAIN-SUFFIX,caiwu.com, 财务部代理"
# - "DOMAIN-SUFFIX,xiaoshou.com, 销售部代理"
- GEOIP,CN,直连
- MATCH,代理

由于并不匹配第1条规则,hwb0307.com继续适配规则GEOIP,CN,直连。由于此前对hwb0307.com并未发起公共DNS请求,因此Clash会发起发起DNS请求(通过nameserverfallback)。然而,hwb0307.com是一个名不见经传的博客,其IP不一定被GEOIP数据库收录,故会跳过规则GEOIP,CN,直连。最终hwb0307.com会走到MATCH,代理;但公司专属DNS服务器可能并不收录hwb0307.com的真实域名IP对。这种结果会导致hwb0307.com无法访问。

此外,对于某些冷门网站,尽管公共DNS解析获取了正确的公网IP,访问域名还是没有办法访问,其警告信息类似:

2023-03-24 16:51:00 WRN [TCP] dial failed error=dial tcp4 公网ip:443: connect: connection refused proxy=直连 lAddr=192.168.1.247:57820 rAddr=XXX.hwb0307.com:443 rule=DomainSuffix rulePayload=hwb0307.com

具体原因比较复杂,可能与电脑/浏览器缓存假IP、使用非443端口有关,我也不甚了解。不过,解决方案是挺简单的,就是hwb0307.com添加到fake-ip-filter

fake-ip-filter:
- "+.baidu.com"
- "+.bilibili.com"
- "+.hwb0307.com"

这样hwb0307.com就可以不使用假IP而总是使用真实IP,从而一定可以成功访问。对Clash而言,fake-ip-filter实际上就是指定某些可能无法正常访问的网站使用redir host模式,它们是无法避免狭义上的DNS泄露的。

小结

配置文件中还有其它模块,不过它们不是本文的重点,故不进行讨论。在本文中,我们解释了Clash的Fake-IP模式结合双DNS服务器(基于双ADGuard Home)是如何保证不同类型的网络访问是如何有条不紊地进行策略分流。

实际上,Openclash的Fake-IP TUN模式 + fallback-filter设置、双AdGuardHome作DNS服务器的方案真心不错

  • 将敏感域名尽可能地添加至rules,最大限度避免DNS泄露。

  • 将敏感域名加入fallback-filter的domain,可以保证远程DNS解析请求强制使用fallback,从而避免域名的DNS污染。 设置GEOIP-CN强制选择nameserver的DNS解析结果,也可以避免非敏感域名的DNS污染。

  • 设置fake-ip-filter强制某些冷门但非敏感的域名不使用fake ip从而保证其可正常访问。

  • 双AdGuardHome设置https/tls的加密上游DNS服务器的可以较大程度降低DNS污染和DNS泄露的影响,特别是在nameserver的AdGuard Home中的DNS黑名单中添加敏感域名的规则列表。

  • 利用docker的macvlan网络模式给nas-tool和transmission分配和路由器/宿主机同网段的局域网IP,这样fake-ip模式下可以设置不走代理的局域网设备IP和排除目的地IP,从而规避PT流量:

msedge_XKwwVVbWVO

整套方案的响应速度和下载速度也不错。不过,如果你深刻地理解了Fake-IP模式,就会发现这种方式其实不太完美。比如:

  • 除了fake-ip-filter里的域名,其它域名的ping值返回的是假IP。这对于想要观察网站真实IP的人而言不太合适(查看Clash内核日志应该看得到;使用chinaz之类的站长工具是一种更好的方案)。以下是示例图:

powershell_CvBBYnL3XU

  • 测速结果不准确
  • 没进行DNS解析的域名是不会有较好的广告屏蔽效果的。

不过,这些缺点我自己并不是很在意啦!此外,我感觉Clash.Meta内核的域名嗅探方式似乎更加好用,但自己的了解比较有限,以后再开坑试试看。

之后可能会讲讲如何在OpenClash的GUI里具体设置某些项目,以达到类似示例配置的效果。敬请期待!另外,相关的知识我也是刚刚学习,很多细节暂时也不太了解。如果有什么意见,欢迎评论区指教喔!

扩展阅读

msedge_gAwcrQqt14

---------------
完结,撒花!如果您点一下广告,可以养活苯苯😍😍😍

感谢ZGOCLOUD友情赞助 (ฅ´ω`ฅ) 本博客基于m2w创作。版权声明:除特殊说明,博客文章均为Bensz原创,依据CC BY-SA 4.0许可证进行授权,转载请附上出处链接及本声明。VIP内容严禁转载!由于可能会成为AI模型(如chatGPT)的训练样本,本博客禁止将AI自动生成内容作为文章上传(特别声明时除外)。如有需要,请至学习地图系统学习本博客的教程。加Telegram群可获得更多帮助喔! | 博客订阅:RSS | 广告招租请留言 | 博客VPS | 致谢渺软公益CDN |

评论

  1. 笨蛋
    Windows Chrome 121.0.0.0
    2 月前
    2024-2-14 11:50:01

    从个人使用角度而言(非公司,公司情况直接用VPN方便一些)Geoip加上no-resolve基本上就不会发起dns请求了,fake-ip在遍历规则后会匹配match,最终导致没被收录到Geosite和Geoip的小众网站会走代理,代理服务器再进行一次DNS查询。本地没有对非CN地区的Geoip和Geosite网站进行DNS查询,保证你上游运营商不知道你访问了海外网站。fake-ip除了部分软件对私有地址无法连接(如游戏、语音等)基本上没什么大问题了吧

    • 博主
      笨蛋
      Windows Edge 121.0.0.0
      2 月前
      2024-2-14 12:15:37

      有类似ADGuard Home之类的强大软件主动分流其实也是一种不错的选择;方案很多,见仁见智了 (~ ̄▽ ̄)~

  2. Andy_Kamansky
    Macintosh Chrome 111.0.0.0
    1 年前
    2023-3-29 12:35:30

    这篇文章看得我头晕。看了好几遍,不明觉厉!保护隐私好重要!

    • 博主
      Andy_Kamansky
      Windows Edge 111.0.1661.54
      1 年前
      2023-3-29 12:36:35

      看得明白自然好,看不明白也不坏 (ฅ´ω`ฅ)

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇