短网址,即 URL Shortener(网址缩短服务),对于博客、媒体、营销等信息发布者而言非常有用。老E关注 YOURLS 等可自托管部署的短链应用主要是由于博客原始长链接会被平台截断,并且视觉体验不好,知名的短链服务平台又经常被污染导致重定向失效。短链项目主要包括两个关键点:
- 通过 HTTP 协议响应码进行跳转。通常包括 301、302、307、308 等状态码,301 和 302 的区别在于是否缓存,缓存是统计、跟踪的前提,307、308 并不常用。详细状态码信息可查阅 MDN 中文文档「重定向消息」。
- Hash 算法和哈希表的维护,采用 62 进制(0-9、a-z、A-Z)冲突概率低,6 位数集合空间大小为 568 亿,足够使用。冲突检测和规避一般结合数据库记录索引解决。
开源的短网址/链接服务应用有很多,不少前端开发者会将其作为练手项目,因为底层门槛不高,所以 UI 很重要。Github 上热门的开源短网址项目简单列举如下:
YOURLS : The de facto standard self-hosted URL shortener
Shlink : The URL shortener
Blink : Modern, lightweight, planet-scale link shortener for teams
Kutt : a modern URL shortener with support for custom domains
Polr : quick, modern, and open-source link shortener
gh-pages-url-shortener : This is a minimal URL shortener that can be entirely hosted on GitHub pages
Url-Shorten-Worker : A URL Shortener created using Cloudflare Worker
YOURLS 和 Shlink 都是基于 PHP 的,Blink、Kutt 和 Polr 则基于 node.js,后两者分别使用 github 和 cloudflare 的免费服务和自定义域名来搭建在线 URL Shortener 服务。
部署环境
这个博客就是 LNMP 下的 wordpress ,自然会选择 YOURLS 或 Shlink,Shlink 需要多安装配置一个客户端(Shlink Client),所以本文就以 YOURLS 为例,介绍短网址应用的部署方法,其他工具大致相同。YOURLS 是的 “Your Own URL Shortener” 的缩写,是一组 PHP 程序,可部署在自己的服务器上,文档齐全,插件支持丰富,支持数据统计等功能。同时,这种仅自用或小范围分享的工具,效率第一,直接在1panel 里开整。
本文使用的示例域名为 sh.example.com,已完成以下工作:
- VPS 安装有 1panel 面板并部署有 LNMP 环境和 www 服务
- 域名解析已完成,CNAME 记录 sh.example.com 指向 VPS
- 泛域名 ( *.example.com ) 证书已申请并有效
以上环境的安装部署本文不做叙述,有关 1panel 可见往期博文「使用1panel快速搭建、发布网站」。
常规部署方法
YOURLS的源代码发布地址为「Releases · YOURLS/YOURLS (github.com)」,可以直接下载源码压缩包。为方便大家使用,这里提供集成了简体中文和部分配置(config.php文件)修改好的「压缩包」,可以「点此」直接下载使用。常规部署需要完成三项工作,分别是创建数据库、创建网站、上传文件。
第一步 创建yourls数据库
首先,示例将创建一个名为yourls的mysql数据库,这在1panel中实现非常简单。1panel左侧导航栏的『数据库』,数据库页面点击『创建数据库』。
定义数据库名称、数据库用户名和密码后,其中的密码 1panel 会自动生成,描述信息可忽略,可以查看或自行指定,最后点右下角的『创建』。
创建完成后,可在数据库概览页面查看数据库密码和连接信息。容器化部署的 mysql 连接信息一般都是 mysql:3306。如果后续出现错误,请检查 nginx/openresty 是否为 host 模式或者和 mysql 处于同一bridge 网络。
第二步 创建网站
数据库创建完成后,接下来创建网站。左侧导航栏的『网站』之下,选择子栏目网站,页面中点击左上角的『创建网站』。
网站创建页面,上方选择『运行环境』(容器化部署则选择『反向代理』)。各项配置可参考如下:
- 『运行环境』:确保为 PHP 7+以上,这是 yourls 的 PHP 版本要求;
- 『PFP-FPM端口』:如果有其他运行环境,需要确保未被占用,本例由默认的 9000 修改为了9100;
- 『主域名』:如果不是单一用途,根域名天然最短、但不建议使用;
- 『代号』:默认与『主域名』相同,建议修改以方便识别,一方面同一域名下可能会有多个服务,另一方面,域名作为主目录名并不一定恰当。
各项参数填写确定后,点击右下角的『确认』以创建网站。
网站创建完成后,我们在容器页面可以查看到已经创建、加载的 php 容器,使用的镜像是已有的。
第三步 上传网站文件、配置网站
下面进行最后一步:上传网站代码文件。为了方便大家使用,可以采用最“偷懒”的方式,即远程下载老E修改的「压缩包」,在线解压后移动至站点主目录下。先简要说明一下修改的部分:
- 添加简体中文语言包,可自行搜索下载后,解压拷贝 zh_CN.mo 和 zh_CN.po 两个文件至 /users/languages/ 下
- 将 sample-public-front-page.txt 复制为同目录下的 index.php
- 将 /user/config-sample.php 复制为同目录下的 config.php
config.php 文件非常重要,最新版本的 yourls config.php 文件相比较早版本选项有所减少,需要关注的选项主要包括:
/* MySQL数据库用户名,请填写 */ define( 'YOURLS_DB_USER', '' ); /* MySQL数据库密码,请填写 */ define( 'YOURLS_DB_PASS', '' ); /* MySQL数据库名称,仅可使用小写字母、数字和下划线,请填写 */ define( 'YOURLS_DB_NAME', '' ); /* MySQL 连接信息,已修改为mysql:3306 */ define( 'YOURLS_DB_HOST', 'mysql:3306' ); /* MySQL表前缀,保持默认 */ define( 'YOURLS_DB_PREFIX', 'yourls_' ); /* yourls站点,如sh.ort可填写为 http://sh.example.com 或 https://sh.example.com,请填写 */ define( 'YOURLS_SITE', 'https://sh.example.com' ); /* 语言,已修改为zh_CN */ define( 'YOURLS_LANG', 'zh_CN' ); /* 是否允许多个短链接对应一个长链接,保持默认为true */ define( 'YOURLS_UNIQUE_URLS', true ); /* 后台管理面板是否使用用户名、密码保护,保持默认为true */ define( 'YOURLS_PRIVATE', true ); /* 用于加密cookies的key,可打开 http://yourls.org/cookie 获得 */ define( 'YOURLS_COOKIEKEY', 'modify this text with something random' ); /* 用户名和密码,可指定多组。 密码可以使用hash,但仅支持md5,方法为密码处为'md5:xxxxxxx...xxx' */ $yourls_user_passwords = [ 'username' => 'password', // 'username2' => 'password2' ]; /* 短链接字符空间,36或62,默认36不包含大写字母,已修改为62包含大写字母 */ define( 'YOURLS_URL_CONVERT', 62); /* 敏感词列表,保持默认或添加 */ $yourls_reserved_URL = [ 'porn', 'faggot', 'sex', 'nigger', 'fuck', 'cunt', 'dick', ];
最后再确认一下目录、文件的属主和权限,针对 1panel 面板,建议将主目录下所有子目录、文件属主设置为 1000。错误的数据库连接信息、用户和密码、文件权限等都会导致错误。勾选 index 目录,点击上方的『权限』,在弹出页面中『用户』和『用户组』都填写 1000 ,此处权限保持 0755 或修改为 0744 均可,注意勾选『同时修改子文件属性』,各项设置完成后,点击『保存』。
远程下载解压,编辑、保存 config.php 文件后,确认是否选择 https,如果需要,可在网站管理页面打开强制 https。『网站设置』页面选择『https』,打开『启用https』,指定或创建证书,配置好各选项后点击『保存』即可。
使用yourls
完成上述步骤后,就可以重载网站并登录后台了。yourls 要求先访问 admin 后台(https://sh.example.com/admin)安装。
快速安装之后,可以使用我们定义的用户名和密码登录管理后台。登录之后,config.php 中的明文密码会自动转为 md5 hash。
登录之后,会看到默认生成的 yourls 官方和作者的 3 个短网址。这里使用之前的博文链接生成一个测试短链,默认采用了顺序码,因此建议添加、使用插件改变短链接生成方式。
Admin 页面点选『管理插件』后,鼠标悬停并点击『Random ShortURLs』右侧的『激活』标签后,Random ShortURLs 就自动激活并会出现在『管理插件』栏下,后续再生成短网址就会采用 6 位随机字符方式(字符空间却决于 config.php 中的定义)。
因为我们重命名复制了 index.php 文件,所以不添加 nginx 伪静态直接访问“裸域名”毫无问题。当前版本的 yourls 从原始设计上是明确不支持“裸域名”访问的,在官方文档的「服务器配置」页面有明确的说明,因此,折腾伪静态、location 重定向规则毫无意义。
By design, this configuration will throw an error 403 "forbidden" on your bare YOURLS server_name domain: it will not answer with an index file on the bare domain, nor on any sub-directory (such as /admin), unless you manually specify /admin/index.php (example: https://your.yourlsdomain.tld/admin/index.php).
容器化部署与二级域名反代
容器化部署过程相对简单,但可能会在 nginx 反向代理环节出现挑战,1panel 应用商店可以直接安装 yourls,安装实际上就是拉取镜像、创建数据库、创建容器的自动化过程。
点击『安装』后,需要配置的内容包括用户名、密码,宿主机端口默认为 40037,均可保持默认,如果需要在本阶段配置环境变量,可勾选『编辑compose文件』,配置完成后,点击『确认』即开始自动安装配置。
安装配置完成后,创建网站,与常规部署不同的是选择『反向代理』,重点是主域名和 yourls 的监听端口,这里是 40037。协议保持默认 http 即可,即使 yourls 容器的环境变量指定了 https 网站 url 也没有关系。配置完成后点击『确认』。
网站创建完成后,如需配置 https 访问 yourls 服务,方法同常规部署。在容器页面,鼠标悬停 yourls 容器栏最右侧的『更多』,弹出菜单中点击『编辑』修改 yourls 站点 url 环境变量(即为 config.php 中的 YOURLS_SITE 参数)和后台用户名、密码,修改完成后点击『保存』。
之后就可以登录 yourls 的 Admin 后台了,url 需要使用 https://sh.example.com/admin。如果希望访问前端(url 不加 /admin),可以修改location,添加适当的重写 url 规则以及伪静态进行测试,但终极方法是直接修改镜像,同常规部署,前端缺少的只是一个 index,php 文件。常规的本地部署 yourls 的“403 forbidden”换成容器化部署后,会体现为 openresty/nginx 的 50x 错误。
附加说明,子路径反代也是可以实现的( YOURLS_SITE 环境变量添加相应子路径),但缺陷是无法访问前端,并且没有稳定的可同时访问前后端、短链接生成、跳转均正常的 nginx 配置解决方案,yourls 的原始设计、apache 的特性、nginx 的特性、容器(docker)隔离等多少存在匹配问题,官方认为通过 nginx 配置子路径反向代理容器化部署的 yourls 服务是很奇怪的需求。官方的意思是,短链短链,你非加个子路径这是要弄啥?安全安全,private 的后端能干为啥非要 public 的前端?确实,这种需求在转换重定向上也存在问题,反复横跳,至少效率非常低下,scheme、header 等数据的传递层层过滤,很难进行二次开发和深度利用。
安全建议
- 使用 1panel 面板容器化部署时,密码无法使用特殊字符,可以采用手动生成密码 md5 值后进入容器编辑 config.php 文件替换,但无法持久化
- 宿主机端口(安装时默认不对外开放)和前端 public 页面不要同时打开,有必要同时打开的话,可配置 WAF 过滤 IP 及 POST 关键字
- 对重定向稳定性和效率不敏感可在内网主机使用 IPv6 部署,借助 mesh network(如netbird)、yourls api 可以实现服务集群
文章评论