add:git推送多个远程仓库

This commit is contained in:
fanxb 2022-02-23 16:59:03 +08:00
parent 71c7007d7e
commit bb55a70f51
8 changed files with 865 additions and 789 deletions

View File

@ -1,126 +1,126 @@
--- ---
id: '2019-03-03-15-42' id: '2019-03-03-15-42'
date: '2019-03-03 15:42:00' date: '2019-03-03 15:42:00'
title: 'docker实现hexo博客自动部署实时更新' title: 'docker实现hexo博客自动部署实时更新'
tags: ['docker', 'hexo', 'next', 'webhook'] tags: ['docker', 'hexo', 'next', 'webhook']
categories: categories:
- '其他' - '其他'
--- ---
## 一、背景 ## 一、背景
  你是否有过想要搭建一个 hexo 博客,但是看着那冗长的教程,唉声叹气?   你是否有过想要搭建一个 hexo 博客,但是看着那冗长的教程,唉声叹气?
  你是否因为每次发布新的博文,都要重新构建,部署而逐渐放弃写博客?   你是否因为每次发布新的博文,都要重新构建,部署而逐渐放弃写博客?
  现在解决有了完美的解决办法了,一键构建,无需进行复杂的配置,开箱即用。同时支持 github 的 webhook 来实现实时构建,只需就行一次 push 操作,便能自动重新构建发布,无需手动操作。   现在解决有了完美的解决办法了,一键构建,无需进行复杂的配置,开箱即用。同时支持 github 的 webhook 来实现实时构建,只需就行一次 push 操作,便能自动重新构建发布,无需手动操作。
  详见[hexoBlog 自动构建](https://github.com/FleyX/hexoBlog)   详见[hexoBlog 自动构建](https://github.com/FleyX/hexoBlog)
使用方法: 使用方法:
## 从 github 克隆本仓库 ## 从 github 克隆本仓库
```bash ```bash
git clone git@github.com:FleyX/hexoBlog.git git clone git@github.com:FleyX/hexoBlog.git
``` ```
## 基本配置 ## 基本配置
1. 修改`docker/docker-compose.yml`文件,指定博文所在 gihub 仓库和 webhook 密钥. 1. 修改`docker/docker-compose.yml`文件,指定博文所在 gihub 仓库和 webhook 密钥.
![docker-compose文件修改](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303145035.png) ![docker-compose文件修改](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303145035.png)
**github 配置 webhock 步骤如下:** **github 配置 webhock 步骤如下:**
  以我的博文仓库(technology-note)为例:   以我的博文仓库(technology-note)为例:
- 新增一个 webhook - 新增一个 webhook
![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303161438.png) ![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303161438.png)
- 配置 webhook - 配置 webhook
![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303161713.png) ![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303161713.png)
  将 url 的地址换为你的服务器地址,然后设置 secret 密钥,就 OK 了。再将密钥设置到 docker-compose.yml 中即可。   将 url 的地址换为你的服务器地址,然后设置 secret 密钥,就 OK 了。再将密钥设置到 docker-compose.yml 中即可。
2. 博文 markdown 文件编写规范,详情参见[分布式事务.md](https://raw.githubusercontent.com/FleyX/technology-note/master/%E6%95%B0%E6%8D%AE%E5%BA%93/%E5%88%86%E5%B8%83%E5%BC%8F/%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1.md) 2. 博文 markdown 文件编写规范,详情参见[分布式事务.md](https://raw.githubusercontent.com/FleyX/technology-note/master/%E6%95%B0%E6%8D%AE%E5%BA%93/%E5%88%86%E5%B8%83%E5%BC%8F/%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1.md)
<!-- more --> <!-- more -->
```yaml ```yaml
--- ---
id: '2018-10-03-10-58' id: '2018-10-03-10-58'
date: '2018/10/03 10:58' date: '2018/10/03 10:58'
title: '分布式事务' title: '分布式事务'
tags: ['分布式', 'sql', '2PC', 'TCC', '异步补偿'] tags: ['分布式', 'sql', '2PC', 'TCC', '异步补偿']
categories: categories:
- '数据库' - '数据库'
- '分布式事务' - '分布式事务'
--- ---
``` ```
参数含义如下: 参数含义如下:
- id博文 id博文链接也会使用这个值 - id博文 id博文链接也会使用这个值
- date: 博文创建日志 - date: 博文创建日志
- title: 博文标题 - title: 博文标题
- tags: 文章标签 - tags: 文章标签
- categories: 文章分类,支持多级分类,第一个最高级依次降低 - categories: 文章分类,支持多级分类,第一个最高级依次降低
&emsp;&emsp;如果想实现首页概览,秩序在想要展现的部分下加上`<!-- more -->`,如下所示: &emsp;&emsp;如果想实现首页概览,秩序在想要展现的部分下加上`<!-- more -->`,如下所示:
![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303150138.png) ![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303150138.png)
3. 在 docker 目录下,执行`docker-compose up -d`,完工,访问服务器 IP 或域名即可看到效果。(注意首次部署可能会很慢,取决于网络情况和服务器配置)。 3. 在 docker 目录下,执行`docker-compose up -d`,完工,访问服务器 IP 或域名即可看到效果。(注意首次部署可能会很慢,取决于网络情况和服务器配置)。
## 详细配置 ## 详细配置
&emsp;&emsp;上图只是基本配置,下面是常用的配置: &emsp;&emsp;上图只是基本配置,下面是常用的配置:
### 设置文章永久链接 ### 设置文章永久链接
&emsp;&emsp;编辑`hexo/_config.yml`下 1617 &emsp;&emsp;编辑`hexo/_config.yml`下 1617
![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303150537.png) ![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303150537.png)
如果部署在根目录下,将 url 设置为`服务器域名`root 设置为`/` 如果部署在根目录下,将 url 设置为`服务器域名`root 设置为`/`
如果部署在 test 路径下,将 url 设置为`服务器域名/test`,root 设置为`/test` 如果部署在 test 路径下,将 url 设置为`服务器域名/test`,root 设置为`/test`
### 设置站点信息 ### 设置站点信息
&emsp;&emsp;编辑`hexo/_config.yml`下 6-10 行,设置博客标题,子标题,关键词,作者等信息 &emsp;&emsp;编辑`hexo/_config.yml`下 6-10 行,设置博客标题,子标题,关键词,作者等信息
```yaml ```yaml
title: Hexo title: Hexo
subtitle: To strive, to seek, to find, and not to yield. subtitle: To strive, to seek, to find, and not to yield.
description: To strive, to seek, to find, and not to yield. description: To strive, to seek, to find, and not to yield.
keywords: ['java', 'node', 'html', 'javascript'] keywords: ['java', 'node', 'html', 'javascript']
author: fleyX author: fleyX
``` ```
**注意下面的都是配置主题的配置文件,位置`themes/_config.yml`,本博客使用的 Next 主题,其他主题的配置可能不一样** **注意下面的都是配置主题的配置文件,位置`themes/_config.yml`,本博客使用的 Next 主题,其他主题的配置可能不一样**
### 设置社交信息 ### 设置社交信息
&emsp;&emsp;编辑第 178 行 social 下项目: &emsp;&emsp;编辑第 178 行 social 下项目:
![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303151851.png) ![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303151851.png)
### 设置打赏 ### 设置打赏
&emsp;&emsp;编辑 327 行 reward 下属性,设置支付宝/微信收款图片,可将图片放到`hexo/source/static/img`目录下。 &emsp;&emsp;编辑 327 行 reward 下属性,设置支付宝/微信收款图片,可将图片放到`hexo/source/static/img`目录下。
![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303152128.png) ![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303152128.png)
### 集成 gitalk 评论 ### 集成 gitalk 评论
&emsp;&emsp;建议百度如何在 github 中配置 gitalk这里默认你已经配置完毕拥有 id 和 secret。编辑 570 行,设置 enable 为 true然后加入你的信息 &emsp;&emsp;建议百度如何在 github 中配置 gitalk这里默认你已经配置完毕拥有 id 和 secret。编辑 570 行,设置 enable 为 true然后加入你的信息
![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303152638.png) ![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303152638.png)
### 集成 cnzz 统计 ### 集成 cnzz 统计
&emsp;&emsp;设置 635 行cnzz id 即可 &emsp;&emsp;设置 635 行cnzz id 即可
![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303152519.png) ![](https://raw.githubusercontent.com/FleyX/files/master/blog/20190303152519.png)
其他更加详细配置参看官方文档。 其他更加详细配置参看官方文档。

View File

@ -1,30 +1,30 @@
--- ---
id: "2018-09-20-10-58" id: "2018-09-20-10-58"
date: "2018/09/20 10:58" date: "2018/09/20 10:58"
title: "git crlf、lf自动转换问题" title: "git crlf、lf自动转换问题"
tags: ["git","crlf","lf","flyway"] tags: ["git","crlf","lf","flyway"]
categories: categories:
- "其他" - "其他"
- "踩坑" - "踩坑"
--- ---
&emsp;&emsp;项目组最近加了一个新功能到代码中,使用 flyway 记录数据库版本变更,该工具会记录每次数据库结构的修改并生成 sql 文件存在指定目录上(当然必须用它来变更数据库,外部的变更它是无法感知的),然后每次启动时 flyway 会检查使用的数据库和当前项目代码中的 sql 变更版本是否一致,一致正常启动,不一致中如果是数据库落后将会更新数据库(这样能够保证代码在任何地方运行数据库都是一致的),否则就报错了。数据库中有一张表记录版本信息,如下图: &emsp;&emsp;项目组最近加了一个新功能到代码中,使用 flyway 记录数据库版本变更,该工具会记录每次数据库结构的修改并生成 sql 文件存在指定目录上(当然必须用它来变更数据库,外部的变更它是无法感知的),然后每次启动时 flyway 会检查使用的数据库和当前项目代码中的 sql 变更版本是否一致,一致正常启动,不一致中如果是数据库落后将会更新数据库(这样能够保证代码在任何地方运行数据库都是一致的),否则就报错了。数据库中有一张表记录版本信息,如下图:
![版本记录](https://raw.githubusercontent.com/FleyX/files/master/blogImg/%E5%85%B6%E4%BB%96%E5%90%84%E7%A7%8D/20190107102736.PNG) ![版本记录](https://raw.githubusercontent.com/FleyX/files/master/blogImg/%E5%85%B6%E4%BB%96%E5%90%84%E7%A7%8D/20190107102736.PNG)
同时本地代码中也有一个文件夹保存每次操作的 sql 语句,如下图: 同时本地代码中也有一个文件夹保存每次操作的 sql 语句,如下图:
![版本sql](https://raw.githubusercontent.com/FleyX/files/master/blogImg/%E5%85%B6%E4%BB%96%E5%90%84%E7%A7%8D/20190107102748.PNG) ![版本sql](https://raw.githubusercontent.com/FleyX/files/master/blogImg/%E5%85%B6%E4%BB%96%E5%90%84%E7%A7%8D/20190107102748.PNG)
通过对比 checksum 值来判断当前 sql 语句和生成数据库的执行语句是否一致checksum 值由 CRC32 计算后处理得出。 通过对比 checksum 值来判断当前 sql 语句和生成数据库的执行语句是否一致checksum 值由 CRC32 计算后处理得出。
&emsp;&emsp;然后问题就来了,组中的其他人搭建好 flyway 后,项目文件生成了两个 sql 文件,我用 git 拉下来后启动报错checkupsum 值对不上,,然后我又不懂这个 flyway 完全不知道咋回事,然后就根据报错的位置一点点找到 checkup 值生成的代码,发现是 CRC32 计算的,,(就这么搞了一两个小时才发现是文件不一致了),但是都是从 git 拉的怎么就我不一致呢???想到可能是文件换行符的问题,遂把那几个 sql 文件的文件换行符全换成了 crlfwindows 中的换行符),然后居然就能够运行。。。关于为啥都从 git 拉取的文件换行符会不一样原因是:他们都用的那个小乌龟的可视化,我用的命令行。可视化工具自动配置了文件换行符的自动转换(这是 git 的一个智能功能,上传时将文件换行符替换为 lf拉取时再替换为 crlf这样保证中心仓库使用 UNIX 风格的换行符,,本地能够根据运行环境使用相对应的换行符风格),但是命令行并没有配置。 &emsp;&emsp;然后问题就来了,组中的其他人搭建好 flyway 后,项目文件生成了两个 sql 文件,我用 git 拉下来后启动报错checkupsum 值对不上,,然后我又不懂这个 flyway 完全不知道咋回事,然后就根据报错的位置一点点找到 checkup 值生成的代码,发现是 CRC32 计算的,,(就这么搞了一两个小时才发现是文件不一致了),但是都是从 git 拉的怎么就我不一致呢???想到可能是文件换行符的问题,遂把那几个 sql 文件的文件换行符全换成了 crlfwindows 中的换行符),然后居然就能够运行。。。关于为啥都从 git 拉取的文件换行符会不一样原因是:他们都用的那个小乌龟的可视化,我用的命令行。可视化工具自动配置了文件换行符的自动转换(这是 git 的一个智能功能,上传时将文件换行符替换为 lf拉取时再替换为 crlf这样保证中心仓库使用 UNIX 风格的换行符,,本地能够根据运行环境使用相对应的换行符风格),但是命令行并没有配置。
&emsp;&emsp;解决办法也很简单,开启 git 的自动转换。 &emsp;&emsp;解决办法也很简单,开启 git 的自动转换。
``` ```
git config --global core.autocrlf true //开启换行符自动转换 git config --global core.autocrlf true //开启换行符自动转换
git config --global core.safecrlf true //禁止混用换行符 git config --global core.safecrlf true //禁止混用换行符
``` ```
ps:最好还是不要开自动切换规定所有人必须使用lf就行了。 ps:最好还是不要开自动切换规定所有人必须使用lf就行了。

View File

@ -1,70 +1,70 @@
--- ---
id: '2019-03-19-15-42' id: '2019-03-19-15-42'
date: '2019-03-19 15:42:00' date: '2019-03-19 15:42:00'
title: '纯html实现svg文件转png/jpg/bmp图片' title: '纯html实现svg文件转png/jpg/bmp图片'
tags: ['html', 'svg转换', 'png', 'jpg', 'bmp'] tags: ['html', 'svg转换', 'png', 'jpg', 'bmp']
categories: categories:
- '其他' - '其他'
--- ---
**源码存放于:**[github](https://github.com/FleyX/demo-project/blob/master/%E6%9D%82%E9%A1%B9/1.svg%E8%BD%ACpng%E3%80%81jpg.html) **源码存放于:**[github](https://github.com/FleyX/demo-project/blob/master/%E6%9D%82%E9%A1%B9/1.svg%E8%BD%ACpng%E3%80%81jpg.html)
&emsp;&emsp;svg 文件实际上是一个 xml 文件,用于描述一个矢量图。可直接用浏览器打开,浏览器会自动解析为图片。但是有时候我们可能会需要将 svg 转成 png/jpeg 等图片格式,有什么简单易用的办法呢? &emsp;&emsp;svg 文件实际上是一个 xml 文件,用于描述一个矢量图。可直接用浏览器打开,浏览器会自动解析为图片。但是有时候我们可能会需要将 svg 转成 png/jpeg 等图片格式,有什么简单易用的办法呢?
&emsp;&emsp;最简单的就是通过 html 来进行转换操作。主要流程如下: &emsp;&emsp;最简单的就是通过 html 来进行转换操作。主要流程如下:
1. 使用`<input type='file'>`获取到文件信息 1. 使用`<input type='file'>`获取到文件信息
```javascript ```javascript
let files = document.getElementById('file').files; let files = document.getElementById('file').files;
``` ```
<!-- more --> <!-- more -->
2. 使用 html5 中的`FileReader`将文件内容读取出来 2. 使用 html5 中的`FileReader`将文件内容读取出来
```javascript ```javascript
for (let i = 0; i < files.length; i++) { for (let i = 0; i < files.length; i++) {
let reader = new FileReader(); let reader = new FileReader();
reader.readAsText(files[i]); reader.readAsText(files[i]);
reader.onload = function(e) { reader.onload = function(e) {
arr.push({ arr.push({
name: files[i].name, name: files[i].name,
content: this.result content: this.result
}); });
}; };
} }
``` ```
3. 使用`DOMParser`解析 svg 内容 3. 使用`DOMParser`解析 svg 内容
```javascript ```javascript
let xml = new DOMParser().parseFromString(item.content, 'text/xml'); let xml = new DOMParser().parseFromString(item.content, 'text/xml');
let svgContent = xml.getElementsByTagName('svg')[0].outerHTML; let svgContent = xml.getElementsByTagName('svg')[0].outerHTML;
``` ```
4. 将 svg 内容放到一个`Image`中,然后再将该 img 写入到 canvas 中,最后将 canvas 画布转为 data 字符串,使用`a`标签下载下来。 4. 将 svg 内容放到一个`Image`中,然后再将该 img 写入到 canvas 中,最后将 canvas 画布转为 data 字符串,使用`a`标签下载下来。
```javascript ```javascript
let img = new Image(); let img = new Image();
img.src = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svgContent))); img.src = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svgContent)));
//这里要等img加载完毕再写到canvas中否则canvas可能为空 //这里要等img加载完毕再写到canvas中否则canvas可能为空
img.onload = function() { img.onload = function() {
let canvas = document.getElementById('canvas'); let canvas = document.getElementById('canvas');
canvas.width = img.width; canvas.width = img.width;
canvas.height = img.height; canvas.height = img.height;
let ctx = canvas.getContext('2d'); let ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, img.width, img.height); ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, img.width, img.height);
//构建下载 //构建下载
let a = document.createElement('a'); let a = document.createElement('a');
a.href = canvas.toDataURL('image/' + postfix); a.href = canvas.toDataURL('image/' + postfix);
a.download = item.name.substr(0, item.name.lastIndexOf('.')) + '.' + postfix; a.download = item.name.substr(0, item.name.lastIndexOf('.')) + '.' + postfix;
//调用点击开始下载 //调用点击开始下载
a.click(); a.click();
}; };
``` ```
# 效果如下 # 效果如下
![svg转png](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190319161059.gif) ![svg转png](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190319161059.gif)

View File

@ -1,59 +1,59 @@
--- ---
id: "2018-09-30-10-58" id: "2018-09-30-10-58"
date: "2018/09/30 10:58" date: "2018/09/30 10:58"
title: "正则匹配之正向/反向预测先行搜索" title: "正则匹配之正向/反向预测先行搜索"
tags: ["java","正则匹配","pattern","预测先行搜索"] tags: ["java","正则匹配","pattern","预测先行搜索"]
categories: categories:
- "java" - "java"
- "正则匹配" - "正则匹配"
--- ---
## 一、背景 ## 一、背景
&emsp;&emsp;今天领导让我写几个正则表达式来对密码做强度验证,听到写正则表达式内心是这样的感觉(哈哈,三分钟搞定,今天又可以打鱼了)。需求如下:密码组成只能是**数字****字母****英文可见半角符号**,然后需要如下 4 个表达式: &emsp;&emsp;今天领导让我写几个正则表达式来对密码做强度验证,听到写正则表达式内心是这样的感觉(哈哈,三分钟搞定,今天又可以打鱼了)。需求如下:密码组成只能是**数字****字母****英文可见半角符号**,然后需要如下 4 个表达式:
- 长度 6 位及以上 - 长度 6 位及以上
- 长度 6 位及以上,包含数字,包含字母 - 长度 6 位及以上,包含数字,包含字母
- 长度 6 位及以上,包含数字,包含字母,包含半角符号 - 长度 6 位及以上,包含数字,包含字母,包含半角符号
- 长度六位及以上,包含数字,包含大写字母,包含小写字母,包含半角符号 - 长度六位及以上,包含数字,包含大写字母,包含小写字母,包含半角符号
&emsp;&emsp;看完需求我就有点懵了,包含数字或者字母我会写,但是同时存在还要在一个表达式中就有点懵了。 &emsp;&emsp;看完需求我就有点懵了,包含数字或者字母我会写,但是同时存在还要在一个表达式中就有点懵了。
## 二、解决方法 ## 二、解决方法
&emsp;&emsp;以第三种为例,这个可以分解为如下需求: &emsp;&emsp;以第三种为例,这个可以分解为如下需求:
- 存在数字 - 存在数字
- 存在字母 - 存在字母
- 存在半角符号 - 存在半角符号
- 长度六位及以上 - 长度六位及以上
关键是如何同时满足前三个条件,在我有限的知识里并不知道怎么搞,然后只好求助于万能的百度了,最终在找了几个小时后发现如下几个关键词,来源[菜鸟教程](http://www.runoob.com/java/java-regular-expressions.html) 关键是如何同时满足前三个条件,在我有限的知识里并不知道怎么搞,然后只好求助于万能的百度了,最终在找了几个小时后发现如下几个关键词,来源[菜鸟教程](http://www.runoob.com/java/java-regular-expressions.html)
- (?=_pattern_) :正向预测先行搜索 - (?=_pattern_) :正向预测先行搜索
名字看着高大上,不明所以,看完示例大概明白什么意思,这个表达式匹配从这个表达式起始的字符串(我也不知道咋解释),就是假设这样一个表达式 abc(?=[abc]) ,用它来匹配 abc123 字符串,(?=[abc])只会对作用于后面的 123这个显然是不匹配的后整个就不匹配了然后关键来了名字里有**预测**两个字,这两个字表名了这个表达式的特性:不占用字符,匹配后如果匹配成功就继续匹配了好像从来不存在这个东西一样,匹配失败就立即返回失败了。利用这个特性我们就可以给正则加限制条件了。 名字看着高大上,不明所以,看完示例大概明白什么意思,这个表达式匹配从这个表达式起始的字符串(我也不知道咋解释),就是假设这样一个表达式 abc(?=[abc]) ,用它来匹配 abc123 字符串,(?=[abc])只会对作用于后面的 123这个显然是不匹配的后整个就不匹配了然后关键来了名字里有**预测**两个字,这两个字表名了这个表达式的特性:不占用字符,匹配后如果匹配成功就继续匹配了好像从来不存在这个东西一样,匹配失败就立即返回失败了。利用这个特性我们就可以给正则加限制条件了。
<!-- more --> <!-- more -->
- (?!_pattern_) :反向预测先行搜索 - (?!_pattern_) :反向预测先行搜索
概念和上面一样但是效果是相反的abc(?![abc]),对于 abc123 是匹配成功的,对于 abca 匹配失败,如下所示: 概念和上面一样但是效果是相反的abc(?![abc]),对于 abc123 是匹配成功的,对于 abca 匹配失败,如下所示:
```javascript ```javascript
reg = /abc(?![abc])/; reg = /abc(?![abc])/;
reg.test('abc123'); reg.test('abc123');
//返回true //返回true
reg.test('abca'); reg.test('abca');
//返回false //返回false
``` ```
&emsp;&emsp;有了上面的知识就能搞定需求啦。 &emsp;&emsp;有了上面的知识就能搞定需求啦。
## 三、结果 ## 三、结果
&emsp;&emsp;对于存在字母我们可以用这样的表达式`(?=.\*?[a-zA-Z]+.\*?),来检查是否存在至少一个字母,最后对于需求 3 的表达式如下:(半角字符我用的 ASCII 码里的 16 进制表示的) &emsp;&emsp;对于存在字母我们可以用这样的表达式`(?=.\*?[a-zA-Z]+.\*?),来检查是否存在至少一个字母,最后对于需求 3 的表达式如下:(半角字符我用的 ASCII 码里的 16 进制表示的)
```javascript ```javascript
^(?=.*?\d+.*?)(?=.*?[a-zA-Z]+.*?)(?=.*?[\x21-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]+.*?)[\da-zA-Z\x21-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]{6,}$ ^(?=.*?\d+.*?)(?=.*?[a-zA-Z]+.*?)(?=.*?[\x21-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]+.*?)[\da-zA-Z\x21-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]{6,}$
``` ```

View File

@ -1,403 +1,403 @@
--- ---
id: "2019-04-05" id: "2019-04-05"
date: "2019/04/25 10:58" date: "2019/04/25 10:58"
title: "最新ubuntu搭建公网个人邮件服务器(基于postfixdovecot,mysql)" title: "最新ubuntu搭建公网个人邮件服务器(基于postfixdovecot,mysql)"
tags: ["smtp", "linux", "ubuntu", "邮件服务器", "postfix", "dovecot"] tags: ["smtp", "linux", "ubuntu", "邮件服务器", "postfix", "dovecot"]
categories: categories:
- "搭建服务" - "搭建服务"
--- ---
&emsp;&emsp;最近做了一个应用,需要用邮件发通知,但是免费的邮箱每天发信数量是有限制的,所以呢就想着搭建一个自己的邮件服务器,能够实现邮件的发送和接收即可,其中大概花了一个星期找资料,测试,终于成功了,写个教程分享给大家。 &emsp;&emsp;最近做了一个应用,需要用邮件发通知,但是免费的邮箱每天发信数量是有限制的,所以呢就想着搭建一个自己的邮件服务器,能够实现邮件的发送和接收即可,其中大概花了一个星期找资料,测试,终于成功了,写个教程分享给大家。
&emsp;&emsp;本教程基于 ubuntu 18.04(其他的 linux 理论上也是可以的只是安装的软件包不一样。用到的主要软件为postfix,dovecot,mysql.废话不多说,下面是教程: &emsp;&emsp;本教程基于 ubuntu 18.04(其他的 linux 理论上也是可以的只是安装的软件包不一样。用到的主要软件为postfix,dovecot,mysql.废话不多说,下面是教程:
<!-- more --> <!-- more -->
# 前置条件 # 前置条件
- mysql 数据库。本教程中使用 mysql 存储域名,用户信息等。 - mysql 数据库。本教程中使用 mysql 存储域名,用户信息等。
- 域名。需要有域名才能实现向公网发邮件/收邮件。这里以 test.com 为例。 - 域名。需要有域名才能实现向公网发邮件/收邮件。这里以 test.com 为例。
- ssl 证书。有不少免费的 ssl 证书提供商,或者使用自签证书,百度即可。 - ssl 证书。有不少免费的 ssl 证书提供商,或者使用自签证书,百度即可。
# 安装环境 # 安装环境
## 安装软件 ## 安装软件
&emsp;&emsp;切换到 root 用户下,执行以下命令: &emsp;&emsp;切换到 root 用户下,执行以下命令:
```bash ```bash
apt update apt update
apt install postfix postfix-mysql dovecot-core dovecot-pop3d dovecot-imapd dovecot-lmtpd dovecot-mysql apt install postfix postfix-mysql dovecot-core dovecot-pop3d dovecot-imapd dovecot-lmtpd dovecot-mysql
``` ```
安装过程中 postfix 会弹出提示: 安装过程中 postfix 会弹出提示:
![选择类别](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425132019.png) ![选择类别](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425132019.png)
这里我们选择第二项Internet Site。 这里我们选择第二项Internet Site。
接着会有如下提示: 接着会有如下提示:
![域名](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425132348.png) ![域名](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425132348.png)
这里填入:`test.com` 这里填入:`test.com`
## 配置 mx 解析 ## 配置 mx 解析
&emsp;&emsp;在域名提供商增加以下解析: &emsp;&emsp;在域名提供商增加以下解析:
- MX 记录:`test.com` 指向 `服务器IP` - MX 记录:`test.com` 指向 `服务器IP`
- A 记录:`pop3.test.com` 指向 `服务器IP` - A 记录:`pop3.test.com` 指向 `服务器IP`
- A 记录:`smtp.test.com` 指向 `服务器IP` - A 记录:`smtp.test.com` 指向 `服务器IP`
## 创建 mysql 数据库 ## 创建 mysql 数据库
&emsp;&emsp;新建一个数据库 mailserver管理账号为admin/123456 &emsp;&emsp;新建一个数据库 mailserver管理账号为admin/123456
&emsp;&emsp;创建虚拟域表,作为认证域。该表是邮件服务器用以接收邮件的域名: &emsp;&emsp;创建虚拟域表,作为认证域。该表是邮件服务器用以接收邮件的域名:
```sql ```sql
-- 建立表 -- 建立表
CREATE TABLE `virtual_domains` ( CREATE TABLE `virtual_domains` (
`id` INT NOT NULL AUTO_INCREMENT, `id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL, `name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 插入一条记录 -- 插入一条记录
insert into virtual_domains values(1,'test.com') insert into virtual_domains values(1,'test.com')
``` ```
&emsp;&emsp;创建用户表,用于用户身份认证。 &emsp;&emsp;创建用户表,用于用户身份认证。
```sql ```sql
-- 创建用户表 -- 创建用户表
CREATE TABLE `virtual_users` ( CREATE TABLE `virtual_users` (
`id` INT NOT NULL AUTO_INCREMENT, `id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT NOT NULL, `domain_id` INT NOT NULL,
`password` VARCHAR(106) NOT NULL, `password` VARCHAR(106) NOT NULL,
`email` VARCHAR(120) NOT NULL, `email` VARCHAR(120) NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`), UNIQUE KEY `email` (`email`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 插入两个用户,以md5加密密码实际应用中应该选择强度更高的算法md5目前以及不安全了 -- 插入两个用户,以md5加密密码实际应用中应该选择强度更高的算法md5目前以及不安全了
insert into virtual_users values(1,1,md5('123456'),'first@test.com'); insert into virtual_users values(1,1,md5('123456'),'first@test.com');
insert into virtual_users values(2,1,md5('123456'),'second@test.com'); insert into virtual_users values(2,1,md5('123456'),'second@test.com');
``` ```
&emsp;&emsp;创建别名表.该表作用相当于当 source 收到邮件时,该邮件会自动转发到 destination 上。 &emsp;&emsp;创建别名表.该表作用相当于当 source 收到邮件时,该邮件会自动转发到 destination 上。
```sql ```sql
-- 创建表 -- 创建表
CREATE TABLE `virtual_aliases` ( CREATE TABLE `virtual_aliases` (
`id` int(11) NOT NULL auto_increment, `id` int(11) NOT NULL auto_increment,
`domain_id` int(11) NOT NULL, `domain_id` int(11) NOT NULL,
`source` varchar(100) NOT NULL, `source` varchar(100) NOT NULL,
`destination` varchar(100) NOT NULL, `destination` varchar(100) NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE) FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE)
ENGINE=InnoDB DEFAULT CHARSET=utf8; ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 插入数据,所有发给first的邮件都会自动转发给second -- 插入数据,所有发给first的邮件都会自动转发给second
insert into virtual_aliases values(1,1,'first@test.com','second@test.com') insert into virtual_aliases values(1,1,'first@test.com','second@test.com')
``` ```
## 生成 ssl 证书 ## 生成 ssl 证书
&emsp;&emsp;生成 ssl 证书可参考这一篇[https://www.jianshu.com/p/b47d862bceeb](https://www.jianshu.com/p/b47d862bceeb).为 test.com 生成 ssl 证书,**假设**证书存放地址为: &emsp;&emsp;生成 ssl 证书可参考这一篇[https://www.jianshu.com/p/b47d862bceeb](https://www.jianshu.com/p/b47d862bceeb).为 test.com 生成 ssl 证书,**假设**证书存放地址为:
- 公钥 /etc/letsencrypt/live/test.com/fullchain.pem; - 公钥 /etc/letsencrypt/live/test.com/fullchain.pem;
- 私钥 /etc/letsencrypt/live/test.com/privkey.pem; - 私钥 /etc/letsencrypt/live/test.com/privkey.pem;
# 配置 postfix # 配置 postfix
&emsp;&emsp;首选备份 postfix 的默认配置文件,然后编辑`main.cf` &emsp;&emsp;首选备份 postfix 的默认配置文件,然后编辑`main.cf`
```bash ```bash
cp /etc/postfix/main.cf /etc/postfix/main.cf.bak cp /etc/postfix/main.cf /etc/postfix/main.cf.bak
vim /etc/postfix/main.cf vim /etc/postfix/main.cf
``` ```
&emsp;&emsp;注释下面的配置: &emsp;&emsp;注释下面的配置:
![注释](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425135857.png) ![注释](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425135857.png)
然后加入如下的配置: 然后加入如下的配置:
```properties ```properties
# 使用自己的ssl证书 # 使用自己的ssl证书
smtpd_tls_cert_file=/etc/letsencrypt/live/test.com/fullchain.pem smtpd_tls_cert_file=/etc/letsencrypt/live/test.com/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/test.com/privkey.pem smtpd_tls_key_file=/etc/letsencrypt/live/test.com/privkey.pem
smtpd_use_tls=yes smtpd_use_tls=yes
smtpd_tls_auth_only = yes smtpd_tls_auth_only = yes
# 使用dovecot来做身份认证 # 使用dovecot来做身份认证
smtpd_sasl_type = dovecot smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination
``` ```
修改 myhostname,myorigin 为如下的值: 修改 myhostname,myorigin 为如下的值:
```properties ```properties
myhostname = test.com myhostname = test.com
myorigin = $myhostname myorigin = $myhostname
``` ```
修改 mydestination 值为 localhost,以启动 mysql 中的虚拟域。: 修改 mydestination 值为 localhost,以启动 mysql 中的虚拟域。:
```properties ```properties
mydestination = localhost mydestination = localhost
``` ```
在配置文件的最后加入以下行,确保将邮件投递给 mysql 表中列出的虚拟域。 在配置文件的最后加入以下行,确保将邮件投递给 mysql 表中列出的虚拟域。
```properties ```properties
virtual_transport = lmtp:unix:private/dovecot-lmtp virtual_transport = lmtp:unix:private/dovecot-lmtp
``` ```
最后加入以下三项参数,告知 Postfix 配置虚拟域、用户和别名 最后加入以下三项参数,告知 Postfix 配置虚拟域、用户和别名
```properties ```properties
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf
``` ```
&emsp;&emsp;接下来创建上面最后加入的三项参数对应的文件。 &emsp;&emsp;接下来创建上面最后加入的三项参数对应的文件。
&emsp;&emsp;创建`/etc/postfix/mysql-virtual-mailbox-domains.cf`,内容如下: &emsp;&emsp;创建`/etc/postfix/mysql-virtual-mailbox-domains.cf`,内容如下:
```properties ```properties
user = admin user = admin
password = 123456 password = 123456
port = 3306 port = 3306
hosts = 127.0.0.1 hosts = 127.0.0.1
dbname = mailserver dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s' query = SELECT 1 FROM virtual_domains WHERE name='%s'
``` ```
接着重启 postfix并测试 postfix 能否找到域,如果成功返回 1 接着重启 postfix并测试 postfix 能否找到域,如果成功返回 1
```bash ```bash
service postfix restart service postfix restart
postmap -q test.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf postmap -q test.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
``` ```
&emsp;&emsp;创建`/etc/postfix/mysql-virtual-mailbox-maps.cf`,内容如下: &emsp;&emsp;创建`/etc/postfix/mysql-virtual-mailbox-maps.cf`,内容如下:
```properties ```properties
user = admin user = admin
password = 123456 password = 123456
port = 3306 port = 3306
hosts = 127.0.0.1 hosts = 127.0.0.1
dbname = mailserver dbname = mailserver
query = SELECT 1 FROM virtual_users WHERE email='%s' query = SELECT 1 FROM virtual_users WHERE email='%s'
``` ```
接着重启 postfix并测试其能否找到邮箱地址成功返回 1 接着重启 postfix并测试其能否找到邮箱地址成功返回 1
```shell ```shell
service postfix restart service postfix restart
postmap -q first@test.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf postmap -q first@test.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
``` ```
&emsp;&emsp;最后创建`/etc/postfix/mysql-virtual-alias-maps.cf`,内容如下: &emsp;&emsp;最后创建`/etc/postfix/mysql-virtual-alias-maps.cf`,内容如下:
```properties ```properties
user = admin user = admin
password = 123456 password = 123456
port = 3306 port = 3306
hosts = 127.0.0.1 hosts = 127.0.0.1
dbname = mailserver dbname = mailserver
query = SELECT destination FROM virtual_aliases WHERE source='%s' query = SELECT destination FROM virtual_aliases WHERE source='%s'
``` ```
同样重启 postfix验证能否正确找到别名并返回 同样重启 postfix验证能否正确找到别名并返回
```bash ```bash
service postfix restart service postfix restart
postmap -q first@test.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf postmap -q first@test.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
``` ```
&emsp;&emsp;如果响应使用 587 端口来进行俺的 smtp 通信,需修改/etc/postfix/master.cf 文件: &emsp;&emsp;如果响应使用 587 端口来进行俺的 smtp 通信,需修改/etc/postfix/master.cf 文件:
取消以下行的注释: 取消以下行的注释:
![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425144459.png) ![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425144459.png)
# 配置 dovecot # 配置 dovecot
&emsp;&emsp;postfix 配置完毕,现在来配置 dovecot首先编辑主配置文件`/etc/dovecot/dovecot.conf`: &emsp;&emsp;postfix 配置完毕,现在来配置 dovecot首先编辑主配置文件`/etc/dovecot/dovecot.conf`:
首先确保下面一行是启用的: 首先确保下面一行是启用的:
```conf ```conf
!include conf.d/*.conf !include conf.d/*.conf
``` ```
然后在配置文件的最后加入如下配置,启用各协议: 然后在配置文件的最后加入如下配置,启用各协议:
``` ```
protocols = imap lmtp pop3 protocols = imap lmtp pop3
``` ```
&emsp;&emsp;修改`/etc/dovecot/conf.d/10-mail.conf`,确保存在以下两个配置: &emsp;&emsp;修改`/etc/dovecot/conf.d/10-mail.conf`,确保存在以下两个配置:
```properties ```properties
mail_location = maildir:/var/mail/vhosts/%d/%n mail_location = maildir:/var/mail/vhosts/%d/%n
mail_privileged_group = mail mail_privileged_group = mail
``` ```
上面的配置将邮件存放目录设置在/var/mail 中,因此将该文件夹的所属人改为 vmail/vmail.命令如下: 上面的配置将邮件存放目录设置在/var/mail 中,因此将该文件夹的所属人改为 vmail/vmail.命令如下:
```bash ```bash
groupadd -g 5000 vmail groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /var/mail useradd -g vmail -u 5000 vmail -d /var/mail
chown -R vmail:vmail /var/mail chown -R vmail:vmail /var/mail
``` ```
&emsp;&emsp;修改`/etc/dovecot/conf.d/10-auth.conf`。首先确保如下两个配置存在且值正确: &emsp;&emsp;修改`/etc/dovecot/conf.d/10-auth.conf`。首先确保如下两个配置存在且值正确:
```properties ```properties
disable_plaintext_auth = yes disable_plaintext_auth = yes
auth_mechanisms = plain login auth_mechanisms = plain login
``` ```
然后修改配置以禁用系统用户登陆,并开启 mysql 支持,如下图所示: 然后修改配置以禁用系统用户登陆,并开启 mysql 支持,如下图所示:
![启用mysql支持](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425150413.png) ![启用mysql支持](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425150413.png)
&emsp;&emsp;修改`/etc/dovecot/conf.d/auth-sql.conf.ext`文件,将内容改成下面的内容: &emsp;&emsp;修改`/etc/dovecot/conf.d/auth-sql.conf.ext`文件,将内容改成下面的内容:
```ext ```ext
passdb { passdb {
driver = sql driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext args = /etc/dovecot/dovecot-sql.conf.ext
} }
userdb { userdb {
driver = static driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
} }
``` ```
&emsp;&emsp;修改`/etc/dovecot/dovecot-sql.conf.ext`: &emsp;&emsp;修改`/etc/dovecot/dovecot-sql.conf.ext`:
首选取消 driver 参数注释并设置为 mysql 首选取消 driver 参数注释并设置为 mysql
```properties ```properties
driver = mysql driver = mysql
``` ```
然后取消 connect 行注释并设置为如下内容: 然后取消 connect 行注释并设置为如下内容:
```properties ```properties
connect = host=127.0.0.1 port=3306 dbname=mailserver user=admin password=123456 connect = host=127.0.0.1 port=3306 dbname=mailserver user=admin password=123456
``` ```
接着取消 default_pass_scheme 行的注释并改为 MD5 接着取消 default_pass_scheme 行的注释并改为 MD5
```properties ```properties
default_pass_scheme = MD5 default_pass_scheme = MD5
``` ```
接着取消 password_query 行的注释并设置为以下信息: 接着取消 password_query 行的注释并设置为以下信息:
```properties ```properties
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u'; password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';
``` ```
最后将`/etc/dovecot`的拥有者改为 vmail:dovecot 最后将`/etc/dovecot`的拥有者改为 vmail:dovecot
```bash ```bash
chown -R vmail:dovecot /etc/dovecot chown -R vmail:dovecot /etc/dovecot
chmod -R o-rwx /etc/dovecot chmod -R o-rwx /etc/dovecot
``` ```
&emsp;&emsp;修改`/etc/dovecot/conf.d/10-master.conf`: &emsp;&emsp;修改`/etc/dovecot/conf.d/10-master.conf`:
首先将 imap-login , pop3-login 下第一个的 port 设置为 0以禁用非 ssl 加密的 imap 和 pop3 协议,如下图所示: 首先将 imap-login , pop3-login 下第一个的 port 设置为 0以禁用非 ssl 加密的 imap 和 pop3 协议,如下图所示:
![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425153728.png) ![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190425153728.png)
然后找到`service lmtp`将其修改为如下: 然后找到`service lmtp`将其修改为如下:
``` ```
service lmtp { service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp { unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600 mode = 0600
user = postfix user = postfix
group = postfix group = postfix
} }
# Create inet listener only if you can't use the above UNIX socket # Create inet listener only if you can't use the above UNIX socket
#inet_listener lmtp { #inet_listener lmtp {
# Avoid making LMTP visible for the entire internet # Avoid making LMTP visible for the entire internet
#address = #address =
#port = #port =
#} #}
} }
``` ```
然后找到`service auth`将其内容修改为如下: 然后找到`service auth`将其内容修改为如下:
``` ```
service auth { service auth {
unix_listener /var/spool/postfix/private/auth { unix_listener /var/spool/postfix/private/auth {
mode = 0666 mode = 0666
user = postfix user = postfix
group = postfix group = postfix
} }
unix_listener auth-userdb { unix_listener auth-userdb {
mode = 0600 mode = 0600
user = vmail user = vmail
#group = #group =
} }
user = dovecot user = dovecot
} }
``` ```
最后找到`service auth-worker`改为如下内容: 最后找到`service auth-worker`改为如下内容:
``` ```
service auth-worker { service auth-worker {
# Auth worker process is run as root by default, so that it can access # Auth worker process is run as root by default, so that it can access
# /etc/shadow. If this isn't necessary, the user should be changed to # /etc/shadow. If this isn't necessary, the user should be changed to
# $default_internal_user. # $default_internal_user.
user = vmail user = vmail
} }
``` ```
&emsp;&emsp;最后要改的就是`/etc/dovecot/conf.d/10-ssl.conf`,以开启 ssl 认证. &emsp;&emsp;最后要改的就是`/etc/dovecot/conf.d/10-ssl.conf`,以开启 ssl 认证.
首先将 ssl 参数改为 required 首先将 ssl 参数改为 required
```properties ```properties
ssl = required ssl = required
``` ```
然后设置 ssl 证书路径就 ok 了,还是用之前的 ssl 证书: 然后设置 ssl 证书路径就 ok 了,还是用之前的 ssl 证书:
```properties ```properties
ssl_cert = </etc/letsencrypt/live/test.com/fullchain.pem ssl_cert = </etc/letsencrypt/live/test.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/test.com/privkey.pem ssl_key = </etc/letsencrypt/live/test.com/privkey.pem
``` ```
&emsp;&emsp;到这里所有的配置都 OK重启 postfixdovecot 后就可以用邮箱客户端(比如 foxmail连接了。 &emsp;&emsp;到这里所有的配置都 OK重启 postfixdovecot 后就可以用邮箱客户端(比如 foxmail连接了。
``` ```
service postfix restart service postfix restart
service dovecot restart service dovecot restart
``` ```
# 结束 # 结束
&emsp;&emsp;配合一个邮件客户端看似很简单,实际上还是有很多坑的,看看上面那么多的配置项就知道了,一定要耐心。 &emsp;&emsp;配合一个邮件客户端看似很简单,实际上还是有很多坑的,看看上面那么多的配置项就知道了,一定要耐心。
&emsp;&emsp;如果无法登陆,可以看看 postfix 和 dovecot 的日志报错情况,再去修改。日志位置在`/var/log` &emsp;&emsp;如果无法登陆,可以看看 postfix 和 dovecot 的日志报错情况,再去修改。日志位置在`/var/log`
**注意**: **注意**:
被这个问题困扰了好几天,未找到解决办法,最后放弃. 被这个问题困扰了好几天,未找到解决办法,最后放弃.
&emsp;&emsp;目前很多主机厂商都不支持和其他服务器的 25 端口通信,已知的有(谷歌云,阿里云),这样就导致在这些机器上搭建的 postfix 邮件服务器,无法向其他的外网邮箱发送邮件,因为无法和其他 smtp 服务器的 25 端口建立连接。貌似是为了避免有人恶意搭建邮件服务器向其他的邮件服务器发送大量的垃圾邮件,从而导致此服务器 IP 被反垃圾邮件组织列入 SML。 &emsp;&emsp;目前很多主机厂商都不支持和其他服务器的 25 端口通信,已知的有(谷歌云,阿里云),这样就导致在这些机器上搭建的 postfix 邮件服务器,无法向其他的外网邮箱发送邮件,因为无法和其他 smtp 服务器的 25 端口建立连接。貌似是为了避免有人恶意搭建邮件服务器向其他的邮件服务器发送大量的垃圾邮件,从而导致此服务器 IP 被反垃圾邮件组织列入 SML。

View File

@ -1,53 +1,53 @@
--- ---
id: '2019-04-02-10-58' id: '2019-04-02-10-58'
date: '2019/04/02 10:58' date: '2019/04/02 10:58'
title: '免费frp内网穿透' title: '免费frp内网穿透'
tags: ['frp', '免费', '内网穿透'] tags: ['frp', '免费', '内网穿透']
categories: categories:
- '其他' - '其他'
--- ---
**此网站已经挂了,需要内网穿透功能的可在下方留言,如果需要的人较多,我会搭建一个内网穿透服务供大家使用** **此网站已经挂了,需要内网穿透功能的可在下方留言,如果需要的人较多,我会搭建一个内网穿透服务供大家使用**
&emsp;&emsp;公司调试需要公网 IP遂在网上找了个免费的内网穿透--[http://ku2.kerwin.cn/](http://ku2.kerwin.cn/)。延迟还行一百多毫秒。 &emsp;&emsp;公司调试需要公网 IP遂在网上找了个免费的内网穿透--[http://ku2.kerwin.cn/](http://ku2.kerwin.cn/)。延迟还行一百多毫秒。
# 使用方法 # 使用方法
## 下载软件 ## 下载软件
&emsp;&emsp;首先下载 frp下载地址[https://github.com/fatedier/frp/releases](https://github.com/fatedier/frp/releases),选择对应的平台和版本,主要版本一定要和网站上的一致。 &emsp;&emsp;首先下载 frp下载地址[https://github.com/fatedier/frp/releases](https://github.com/fatedier/frp/releases),选择对应的平台和版本,主要版本一定要和网站上的一致。
<!-- more --> <!-- more -->
## 编写配置文件 ## 编写配置文件
&emsp;&emsp;解压压缩包后编辑 frpc.ini &emsp;&emsp;解压压缩包后编辑 frpc.ini
```properties ```properties
[common] [common]
server_addr = frp.kerwin.cn server_addr = frp.kerwin.cn
server_port = 7000 server_port = 7000
token = kerwin.cn token = kerwin.cn
# 名称随意,只是一个标识 # 名称随意,只是一个标识
user = fleyx user = fleyx
[web] [web]
type = http type = http
# 本地ip地址 # 本地ip地址
local_ip = 127.0.0.1 local_ip = 127.0.0.1
# 要穿透的端口 # 要穿透的端口
local_port = 8082 local_port = 8082
# 可以将自己的域名cname到ku2.kerwin.cn # 可以将自己的域名cname到ku2.kerwin.cn
# 如果没有自己的域名那也是可以的可以在frp页面看别人的域名然后在定义locations就可以将此路径下的请求发送到本机 # 如果没有自己的域名那也是可以的可以在frp页面看别人的域名然后在定义locations就可以将此路径下的请求发送到本机
# 下面这个域名就是别人的,然后我顺便借用下 # 下面这个域名就是别人的,然后我顺便借用下
custom_domains = ck1.ck2014.win custom_domains = ck1.ck2014.win
# 穿透路径 # 穿透路径
locations = /fleyx locations = /fleyx
``` ```
## 启动 ## 启动
&emsp;&emsp;启动命令如下: &emsp;&emsp;启动命令如下:
```bash ```bash
./frpc -c frpc.ini ./frpc -c frpc.ini
``` ```

View File

@ -1,48 +1,48 @@
--- ---
id: "20190430" id: "20190430"
date: "2019/04/30 10:58" date: "2019/04/30 10:58"
title: "安利一个PS4游戏折扣查询的小工具" title: "安利一个PS4游戏折扣查询的小工具"
tags: ["PS4", "折扣", "提醒"] tags: ["PS4", "折扣", "提醒"]
categories: categories:
- "其他" - "其他"
--- ---
几个月前经受不住诱惑买了 PS4港服的账号发现商店不是那么的好用遂想找一个查价格/折扣的小程序但是呢没发现很好用的switch 的主掌中宝就做的很不错),所以就自己做了一个。 几个月前经受不住诱惑买了 PS4港服的账号发现商店不是那么的好用遂想找一个查价格/折扣的小程序但是呢没发现很好用的switch 的主掌中宝就做的很不错),所以就自己做了一个。
![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190430103928.png) ![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190430103928.png)
断断续续开发了一个多月,基本功能都已实现。 断断续续开发了一个多月,基本功能都已实现。
<!-- more --> <!-- more -->
已实现功能如下: 已实现功能如下:
- ps4港服 游戏折扣信息以及已近全部收录 - ps4港服 游戏折扣信息以及已近全部收录
- 支持关键词搜索 - 支持关键词搜索
- 支持按照语言、游戏类别等分类查询,按照游戏发现时间、热度等排序 - 支持按照语言、游戏类别等分类查询,按照游戏发现时间、热度等排序
- 支持关注游戏折扣提醒 - 支持关注游戏折扣提醒
- 微信消息通知。需要在折扣发生的七天内使用过本小程序才能推送微信通知(微信的限制) - 微信消息通知。需要在折扣发生的七天内使用过本小程序才能推送微信通知(微信的限制)
- 邮件提醒。需要绑定自己的游戏,并把发验证码的那个邮箱地址加入到白名单中(可能会被某些邮件服务商当成垃圾邮件) - 邮件提醒。需要绑定自己的游戏,并把发验证码的那个邮箱地址加入到白名单中(可能会被某些邮件服务商当成垃圾邮件)
正在开发功能如下: 正在开发功能如下:
- 查看游戏的奖杯信息 - 查看游戏的奖杯信息
- 绑定PSN ID查看自己的基本信息和奖杯信息 - 绑定PSN ID查看自己的基本信息和奖杯信息
# 界面截图 # 界面截图
## 主界面 ## 主界面
![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190611103707.jpg) ![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190611103707.jpg)
## 详情页面 ## 详情页面
![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190611103726.jpg) ![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190611103726.jpg)
![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190611103743.jpg) ![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190611103743.jpg)
## 关注页面 ## 关注页面
![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190611110854.jpg) ![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190611110854.jpg)
**PS**有兴趣一起开发的邮件我fanxb.tl@gmail.com **PS**有兴趣一起开发的邮件我fanxb.tl@gmail.com

View File

@ -0,0 +1,76 @@
---
id: "20220223"
date: "2022/02/23 10:38:05"
title: "git配置多个远程地址"
tags: ["git", "私有仓库", "gitlab", "gogs"]
hide: false
index_img: https://qiniupic.fleyx.com/blog/202202231638624.png?imageView2/2/w/200
banner_img: https://qiniupic.fleyx.com/blog/202202231638624.png
categories:
- "其他"
---
天下苦 github 久已,鉴于国内网络环境对 github 的种种限制,导致 github 的使用体验比较差,于是考虑搭建一个私有的 git 代码管理平台。对比了多种方案最后选择了[gogs](https://gogs.io/),主要优点如下:
- 底层基于 go运行速度很快资源消耗低
- 功能简介,没有各种花里胡哨的功能
- 代码开源
<!-- more -->
具体部署过程不在这里展开,官网有详细的中文文档。
**PS不要使用 gogs 自带的 ssh 服务,支持的协议比较少。如果物理机部署直接用物理机的 ssh 就行了,如果 docker 部署可将其它端口映射到 docker 容器的 ssh 端口(22)**
那么问题就产生了,如果有些项目需要推送到 github 怎么办?
配置多个远程地址即可,按需推送到远程。方法如下:
## 支持多个远程地址,实现默认拉取,推送操作私有地址
1. 先将 github 的 remote 名改为 github
```bash
git remote rename origin github
```
2. 再增加私有平台的 ssh 地址
```bash
git remote add origin ssh://xxxxxxxxxxxxxxxxx.git
```
3. 拉取私有平台的 master 地址
```bash
git pull origin master
```
4. 将本地 master 和私有平台 master 关联起来,实现操作操作私有平台
```bash
git branch --set-upstream-to=origin/master master
```
关联后,执行 git push,git pull 命令默认都是操作的 origin也就是私有平台
## 拉取推送 github
操作非默认分支时需要指定远程地址
```bash
# 表示拉取远程 master 分支
git pull github master
# 表示推送到 github 上
git push github
```
## 进行分支切换
当切换到一个远程分支时需要指定远程地址,比如下面命令切换到 origin/dev 分支:
```bash
git checkout --track origin/dev
```
**PS:在进行 push 操作前最后先 pull 一次。**