ubuntu appstream错误

因为要做个数据库迁移测试,所以给安装了一个ubutnu16.0.4的本地环境镜像虚拟机,安装结束后执行基本操作

sudo apt update

结果系统告诉我无法获得锁/var/lib/apt/lists/lock,紧接着就是报告了内部错误
错误显示为appstream报错,网上查了一下,appstream是几个主要GNU/Linux提供者之间的协议,目的是为了创造一个Linux上的 共同的软件安装程序以及一个同意的软件安装图形用户界面,还有分享元数据用的.
这里报错错误的原因是,ubuntu16.0.4内置的libappstream是2.0以前的版本,我们必须更新到3.0以上的版本才可以
解决办法很简单,只要安装libappstream3就可以了,在ubuntu下安装非常简单,直接通过apt安装就可以了

通过apt安装appstream

通过apt安装appstream非常简单,执行执行命令就可以了

sudo apt-get purge libappstream3
sudo apt update

最后一切搞定

记一次nginx重定向操作

引言

今天有一个朋友,需要配置一个301重定向,需求是要把xxx.com下所有的请求全部重定向到www.xxx.com 下来.同时xxx.com后面所有的参数全部都要去掉,感觉是非常奇怪的请求,朋友操作很久之后未果,于是就让我帮忙看看,这里是一个非常简单的操作,但是仍然踩了一些坑,于是准备记录一下,避免自己在未来或者其他的人踩坑

配置

首先配置非常简单,这里是nginx服务器,所以只要配置一个rewrite就可以了,配置代码如下(仅显示相关配置代码)


server_name xxx.com www.xxx.com; ........ if ( $host != 'www.xxx.com' ){ rewrite ^.*$ http://www.xxx.com/ permanent; break; }

这里的配置需要注意的是,我在重定向的域名后面加上了/符号,如果不加这个符号,那么像xxx.com/somesting 这样的请求会重定向到http://www.xxx.com/somestring ,也就是说这里会自动的把后面的目录和参数加到重定向域名的后面,就相当于这样的配置

if ( $host != 'www.xxx.com' ){
    rewrite  ^/(.*)$  http://www.xxx.com/$1   permanent;
    break;
}

这里应该是是nginx的一个特性,加上/符号之后就不会有了

遇到的问题

一开始我告诉朋友这个配置的时候,并没有效果,于是我觉得很奇怪,因为在我的印象中,这个配置不可能有问题的,ping一下域名,发现对方有一个隐性url解析,解析是@主机记录,解析的位置是www.xxx.com , 于是这里就非常有意思了,ping www.xxx.com 这个域名的时候,是正确的服务器ip地址,但是ping xxx.com的时候,这个地址就是一个其他无关的地址,所以导致解析没有办法生效.
这里我想说的是,在配置web服务器的时候,域名解析和web服务器配置是相关联的,在一次http请求过程中,首先是查询dns找到域名的主机位置,然后才会把请求转发给服务器,交给服务器接管,这里和操作系统的启动有点类似,bios加载了引导之后才会把控制权交给操作系统.

尾语

这一次经历虽然短暂,但是让我对一个信念认识的更加深刻了 ,条条大路通罗马 , 实现一个重定向配置,不仅仅是可以通过web服务器来解决的,这里就至少有三个解决方案了,首先是通过域名解析的时候,对域名进行隐性的解析能够生效,其次就是配置web服务器了,再者其实可以使用php代码来对请求做处理,多种多样的手法,于是我们怎么配置怎么来了.
不过要说功能更全面的话,还是要了解web服务器最好,比如这里的特殊需求,要xxx.com/somestring 在重定向之后删除后面所有的多余字符串,虽然我不明白这么做的用意是什么,但是这个需求web服务器搞定是没有问题的.
最后坚定一下信仰,nginx作为一个轻量级的服务器其实真的不仅仅是清量那么简单,真的是功能非常齐全的.

使用ssh config配置克隆非22端口的repos

前言

前段时间在本地局域网环境搭建了个gitlab,于是就用反向隧道把局域网的gitlab服务通过云服务器映射到外网了,但是通过ssh协议克隆仓库的时候出现了一点问题,踩了一些坑,于是记录下来,避免有更多的人踩这个坑

环境

  • 域名 gitlab.crisen.org
  • 端口 2222
  • 仓库名称 test
  • 仓库地址 git@git.crisen.org:crisenchou/test.git

遇到的问题

因为我的gitlab服务器是通过反向隧道建立的,所以走的不是22端口,那么直接通过git clone的方式是没有办法进行克隆的,通过查询一些资料,知道了有两种方法来实现这个仓库的克隆

通过ssh config

在~/.ssh目录下,编辑一个config文件

vim ~/.ssh/config

添加下面的内容

Host gitlab
    Hostname git.crisen.org
    Port 2222
    User git

Host 表示别名 Hostname表示服务器地址,可以是ip的形式 Port为端口 User指定用户

接下来只要在本地以下面的形式来克隆仓库就可以了

配置config之后 不能直接克隆仓库地址来克隆 而是下面的命令

git clone git:crisenchou/test.git

这里的gitlab别名 等价于git@git.crisen.org -p2222 所以是上面的命令 而不是直接用地址来克隆
这一步非常关键

通过ssh协议

使用这种方法会更加简单一些,不过要输入的字符多一点,多个仓库的情况下,还是配置来的更好一点,它的命令如下

git clone ssh://git@git.crisen.org:2222/crisenchou/test.git

尾语

我是因为云服务器的内存不够,而且考虑到内网环境下,使用内网的git服务器更加迅速,所以在局域网搭建了gitlab服务器,再加上我在外网的环境下有时候也需要用到这个git服务,索性就自己捣腾了一下,虽然踩坑是无法避免的,但是在踩坑的过程中不断的成长,我觉得才更有意义.

命令行(command not found)

初学者在接触命令行的时候,肯定会经常碰到command not found这样的提示,有些时候可能会因此困惑,我明明是有这个文件的,但是为什么找不到命令呢

windows or *nix

windows下的命令行用起来的感觉差强人意,如果使用命令行还是使用*nix(linux,unix)比较好,这里默认使用linux的bash来进行解释

shell运行命令的方式

bash中,有四种命令可以在终端执行,分别是函数和别名,内建命令,外部命令,以及可执行文件

在windows下的可执行文件是以.exe .bat .sh后缀名结尾的文件,但是在linux下任何文件只要有x可执行权限都可以执行 (x可执行权限表现为使用ls -al命令中出现为最前面的十个字符,分别表示文件类型 拥有者权限 用户组全选 其他用户权限)

函数和别名

在终端下可以通过在shell的配置文件中编写函数来作为命令使用,比如在homestead虚拟机中有一个函数artisan,使用type artisan可以看到artisan的代码

默认的shell文件是/etc/profile 和.profile,而bash的默认配置文件则是/etc/bash.bashrc和.brshrc,其中etc目录下的是全局配置文件, .号开头的是用户专属配置文件

artisan()
{
php artisan "$@"
}

当使用artisan命令的时候,shell会调用php去执行当前目录下的artisan文件,并把所有的参数一起传递过去,通过这个函数,就可以让我们不用每次都输入php artisan "arguments"来工作了

还有一种是别名,比如ll命令,通过内建命令alias命令可以创建别名,比如使用type ll的时候,就可以很清晰的看到
ll is aliased to `ls -alF'

内建命令

内建命令其实就是shell本身中已经编写好的指令,这些指令通常是不能用which查看到的,比如cd history命令等,在命令行使用type 命令可以看到一个命令是什么类型的命令,比如使用

type  history

就能看到输出 history 是shell 内建

history 显示当前用户使用过的所有的命令记录

外部命令

那么接下来外部命令是什么?
在解释外部命令之前,先引入一个词汇环境变量,你应该或多或少的听过它的另一个命令PATH,在终端下输入下列命令就可以看到当前所有的环境变量了, 其实它就是很多路径组成的集合

echo $PATH

如果是windows下 则是echo %PATH%

因为当从终端输入字符之后,shell会执行下面三个步骤
- 判断命令是不是函数或者别名(函数和别名拥有执行的最高优先级)
- 判断命令是不是内建命令
- 在环境变量的所有路径下寻找与命令匹配的文件

如果这些过程都没有找到可执行文件,那么就会返回command not found 或者未找到 xx 命令这样的错误信息了

如果在执行命令的时候,直接指定了完整路径的话,那么shell将不会执行这三个步骤,从而定位到该文件来执行该命令

可执行文件

在linux中,默认的所有的可执行程序都必须有路径才可以执行,其实外部命令也是一个可执行文件,这里为了区分外部命令,定义为带有路径执行的可执行文件,如./a.out 就是一个非常常见的一个可执行文件

a.out 是gcc不加任何参数编译输出的默认的文件

这里我想要表达的是,linux下任何一个文件,给出完整路径后,可以在任何目录下执行,而不依赖于环境变量
比如ls 命令,直接使用ls -al可以列出当前目录下的所有文件,而它所在的路径一般是/bin/ls
所以在终端下输入

/bin/ls -al

ls -al是完全一样的

尾语

当你一个命令不是函数,别名,内建命令,也不是外部命令,也没有给出完整路径 仍然都找不到命令的话,那么就只有两种原因
- 你的计算机里没有安装这个程序
- 你的命令输入错了
最后让command not found都见鬼去吧

记一次数据恢复

引言

今天一位小兄弟准备实现一遍从删库到跑路的创举,于是把数据库里面的所有数据都给清空了,这一番操作可就苦恼我了,数据丢失那可是非常严重的问题,必须要对数据库进行恢复

恢复数据的过程

看到数据库为空的那一瞬间,我的大脑其实是不清醒的,然后那个瞬间我突然想起,我曾经写过一个定时脚本,它会在每天凌晨的三点钟对数据库进行全量备份。
在/var/mysql-backup目录下找到了20180426.sql的备份。于是先恢复一部分数据先,使用mysql的终端执行了下面的命令

mysql -uroot -p
use xxxdatabase;
source /var/mysql-back/20180426.sql

这样就把数据恢复到了晚上凌晨三点的状态,但是仅仅这样还是不够的,发现失去数据的时间为下午3点钟,这就是说从凌晨3点到下午3点整整12个小时的数据全部丢失,这样的损失仍然是无法接受的
于是检查一下/etc/my.cnf,发现我的习惯还是不错的,二进制日志默认开启,那么事情就简单了,只要把这个时间节点的二进制日志导出,继而恢复即可

基于二进制日志对数据库进行恢复

首先找到二进制日志所在的目录/var/mysql/,找到最近的二进制文件名称为mysql-bin.000011,
接下来在命令行下使用mysqlbinlog命令,导出这段时间的记录

ps 这里加上了--no-defaults 参数,因为在我的mysql5.7中 不加这个参数执行会出现mysqlbinlog: [ERROR] unknown variable 'default-character-set=utf8mb4'这样的错误

mysqlbinlog  --no-defaults    --start-datetime="2018-04-26 03:00:00" --stop-datetime="2018-04-26 15:00:00"  /data/mysql/mysql-bin.000011 > backup

这样就把这个时间点的数据全部导出到了backup中,然后用输入重定向的方式执行命令
~~~
mysql -u oort -p < backup
~~~~
然后检查了一下数据库,发现数据都回来了,完美的解决了问题

总结

数据是重中之重,定时脚本每天备份是必不可少的操作,然后二进制日志一定要开启,不要在乎那一点点的性能损耗,我们有必要用性能来换取数据库的容灾性。并且在有条件的情况下,请使用多台数据库做主从的操作,来保证数据库的容灾性质,

端口转发与反向隧道

引言

最近了解到一个叫做反向隧道的东西,发现这个可以用来很多黑科技的事情,于是就尝试了一下

准备材料

  • 一台云服务器
  • 一台带有ssh client的计算机

ssh动态端口转发

ssh有三种转发模式,本地端口转发 远程端口转发 动态端口转发,对应的参数分别是 -L -R -D
如果仅仅作为正向代理服务器的话,我们只要使用动态端口转发就可以了(这里只介绍动态端口转发进行科学上网,ssh更详细的用法还是查看手册比较好)

ssh -D  localhost:1991 root@server_ip

这样就在本地的1991端口开启了一个socks代理,接着是配置火狐浏览器的代理功能首选项->设置->手动设置代理

socks主机: localhost
端口: 1991

这样当前计算机就能通过1991端口,转向到云服务器从而获取网络资源了 ,不过这样只能给本机使用,如果希望当前局域网内的所有计算机使用的话,只要稍微改一下地址就可以了,假设本地计算机的ip地址是192.168.10.10,那么使用命令如下

ssh -D 192.168.10.10:1991 root@server_ip

这样在火狐浏览器中的配置就是

sockes主机: 192.168.10.10
端口: 1991

配置到局域网的ip之后,本地局域网内的所有计算机都可以通过这个ip进行代理,但是本机不能使用127.0.0.1的地址进行代理,如果你希望本地使用127.0.0.1 的方式并且局域网的其他计算机也可以访问的话,那么还是上一条命令稍稍做一下修改就可以了

ssh -D 0.0.0.0:1991 root@server_ip

这样本地使用127.0.0.1 或者局域网其他计算机使用192.168.10.10 就都可以使用代理服务器了

0.0.0.0其实不算是一个ip地址,它代表 的是你计算机上所有的ip地址

尾声

工具能够帮助你更好的完成一些复杂的任务,但是基础知识能够让你更加灵活的运用工具。

linux下分割文件

linux下分割文件

在 linux下工作的时候,总是需要对文件进行分割的时候,比如文件太大又或者希望把一段敏感信息分开存储,这个时候linux下强大的split就登场了,split工具分割文件的方式有两种,一种是以行的形式,另外一种是以二进制的形式

split的参数(split 8.25)

  • -a 分割后的文件的前缀
  • -b 以二进制方式分割文件
  • -C 每个输出文件的最大值
  • -d 以数字形式输出文件名
  • -e 不输出空文件
  • -l 以行的形式分割文件
  • -n 生成chuncks输出文件

实际用法

比如有一个文件名为file,大小为4M,那么可以通过下面的命令来切成4片

  • 二进制形式分割
split -b 1M  file

那么就会生成xab xac xad xae四个文件

  • 生成带上数字形式的文件
split -b 1M  -d file

带上了-d参数,那么生成的文件将会是x01 x02 x03 x04

  • 指定生成的文件的前缀
split -b 1M  -d file  suffix

那么生成的文件将会是suffix01 suffix02 suffix03 suffix04

  • 以行的形式分割

如果是文本文件,那么可以用-l 数字以行的形式进行分割

split -l 10 file

合并文件

分割之后必定有合并,否则就好像不怎么完整,不过合并就没有专用的工具了,但是还是一条命令就可以解决的 ,比如分割后的文件是xac xab xac xad四个,那么使用这样的命令

cat x* > newfile

这样新生成的文件newfile和原来的file文件就是一样的,使用md5sum工具可以计算出,他们具有相同的md5值

尾语

通过split工具,我们不仅仅可以单纯的把它当作一种切割文件的工具,其实也可以当作一种加密工具,有些时候自己个人的隐私数据保存成文本十不安全的,加密的话是一种选择,不过我还是更倾向于把文件分割开来,分开存储,需要的之后组合起来就能看到自己想要的数据了。未尝不是一种好的手法。linux下的工具丰富强大,怎么选择还是看个人,不过这一切都需要依靠自己主动的去探索。

利用ssh反向隧道控制内网计算机

引子

今天有个朋友告诉我他们 公司把teamviewer的端口封掉了,所以没有办法在家里控制公司的电脑去完成一些任务,于是就问我怎样进行内网穿透。这个时候我第一时间想到的是,通过在一台有公网ip的服务器上编写socket服务器,然后在客户端利用socket连接到服务器,连接到之后,把从服务器接收到的信息当做命令来执行,这样等于就是开了一个后门,可以实现内网穿透。正在我准备编写socket服务端代码的时候,我的直觉告诉我,这么简单的功能肯定已经有前辈实现了,本着不重复造轮子的良好习惯,于是顺手搜索了一下ssh,于是了解到反向隧道可以实现这个功能。

准备环境

  • 一台具有公网ip的服务器(必须开启sshd服务)
  • 一台unix/linux系列的客户端(必须开启sshd服务)

实现原理

这种手段的实现方式是,通过当前unix/linux客户端向服务器主动的建立一个SSL隧道,然后将服务器上的某个端口转发到当前客户端的22端口上,这样任何一台计算机包括服务器本身,都能使用服务器上开启的某个端口连接到当前的客户端上

实现过程

要先实现这个过程非常简单,现在定义服务器名称为S,服务器的ip地址为SADDR,服务器用户为root,需要开启的端口任意,这里使用7777, 客户端计算机的名称为C,客户端计算机的用户user
在C上使用命令主动的向S建立ssh隧道

ssh -p 22  -qngfNTR 7777:127.0.0.1:22  root@SADDR

这样一条命令就能在客户端C上建立了一条链接服务器S的ssh隧道
然后在S上就可以通过7777端口来连接到客户端C了,使用命令如下

ssh -p 7777 user@127.0.0.1

如果是其他计算机,那么可以使用下面的命令来连接

ssh -p 7777 user@SADDR

这样就完成了从外网利用ssh来访问内网的计算机了,当然ssh的 功能肯定不止这么一点,更多的功能就不多做介绍了,想要掌握更多的知识,最终还是需要自己去探索的。

工欲善其事必先利其器(二)—–vagrant

学会使用虚拟机之后,那么我们一定会面临一个比较棘手的问题:我们应该如何来管理这些虚拟机?因为我们常用的虚拟机都是配置好的,熟悉的环境,熟悉的工具。重复配置无疑是一种浪费时间的行为,为了避免这种浪费,那么我们需要一个强有力的工具vagrant.

什么是vagrant

Vagrant is a tool for building and managing virtual machine environments in a single workflow.

来自于官方的说法,vagrant就是专门用来建立和管理虚拟机环境的工具。

vagrant是用ruby语言编写的,在vagrant中所有的虚拟机环境都来自于一个叫做box的文件,通过 配置Vagrantfile,指定需要使用的box,然后配置cpu核心数量,内存大小,网络,共享文件,登录凭证等信息,可以快速的得到一个已经配置好的虚拟机环境。其实大多数配置都是可以省略的,最便捷的配置文件甚至只有一条配置。

什么场景下应该使用vagrant

抛开场景谈工具都是耍流氓,每一种工具都有它最适合存在的地方。虽然平时作为个人使用的时候,我们大多用来迁移和管理自己的虚拟机,但是我觉得它最实用的地方就是“团队协作”。每个人都会有自己的使用习惯,有些人习惯mac,有些人习惯linux,还有人则习惯用windows。哪怕同样用的是windows,也有win7和win10等各种区别,就算同样用的win7或者win10,那么大家用的IDE也可能都是不一样的。linux更不用说了,对应着各种不同的发行版。这个时候vagrant的强大就体现出来了,不管用户所使用的操作系统是何种类别,都能保证开发环境的一致性。这样可以避免开发过程中,因为环境不一致所带来问题。

获取vagrant

vagrant下载页,  可以获得最新版的vagrnat版本,有debian,windows,centos,mac.arch linux等各种版本可以选择,如果是ubuntu操作系统的话,除了可以使用debian的deb安装包来安装,还可以使用apt命令进行安装

sudo apt install vagrant

不过通过apt安装的vagrant版本不是最新版本,请酌情使用

vagrant操作

vagrant操作系统的基本操作非常简单,只有简单的几条命令

vagrant init  初始化虚拟机

vagrant up 启动虚拟机

vagrant provision 应用虚拟机配置

vagrant halt  关闭虚拟机

vagrant destroy 摧毁虚拟机

vagrant ssh  进入虚拟机终端

获得vagrant官方基本系统环境hashicorp/precise64的方法非常简单,只需要运行命令


vagrant init hashicorp/precise64
vagrant up

就可以获得一个基础的虚拟机环境了,不过需要注意的是,因为vagrant的box有时候体积比较大,在执行下载的过程中可能会非常缓慢甚至是没有办法获得资源的情况,如果在运行命令的过程中出现超时或者卡主的情况,可以在后面找到解决的办法

vagrant的box

vagrant官方提供了一系列的box下载,在下载页中,支持最多的虚拟机就是virtualbox,

vagrant中添加box的命令如下

vagrant box add  box名称 box路径     ps:可以是网络路径或者是本地路径

可以添加本地路径的box,那么我们可以先从下载页把box下载到本地,然后本地环境添加hashicorp/precise64,接着执行

vagrant init hashicorp/precise64
vagrant up

就能快速得到一个可用的虚拟机环境了

如果要查看当前可用的box,可以使用命令
vagrant box list

制作属于自己的box

box除了可以从网上获取之外,还自己制作,除了可以从无到有制作一个box,还可以在已有的box之上,添加一些定制功能,把它变成只属于自己的box

在vagrant中有一条命令,可以打包属于自己的虚拟机

vagrant package --base 虚拟机标识 --output box名称

ps:虚拟机标识不是在虚拟机页面显示的名称,这个标识需要通过命令vboxmanage list vms来得到,其中vboxmanage命令是virtualbox自带的工具,如果是其他虚拟机的话,则需要其他工具来获取

在使用vagrant中可能会遇到的问题

  • 在执行vagrant up过程中,出现超时或者卡住的现象,这个是因为网络的问题,因为在国内的网络速度不是很给力,而且还有GFW的存在可能没有办法获取到资源,不过这个可以通过添加本地box的方式或者通过科学上网工具来解决
  • vagrant up过程中,ssh配置失败,这个现象发生的原因有很多种,调试方法是打开gui选项,看看是否出现故障,其次是可以通过ssh vagrant@ip  password:vagrant 登录到虚拟机 手动配置ssh权限即可
  • 更多问题请仔细阅读vagrant官方文档,或者通过stackoverflow寻找解决方案