- 安装后,dnsmasq默认使用文件/var/run/dnsmasq/resolv.conf作为上游名字服务列表文件
Ubuntu 安装VirtualBox增强功能
首先保证虚拟机已经挂在增强功能的安装盘
以下命令均需要使用root用户登录或使用sudo执行
然后安装下面的软件包
apt-get install gcc make
然后,挂载光盘
mount /dev/sr0 /media/cdrom
最后,打开目录执行安装脚本即可,安装完之后需要重新启动
cd /media/cdrom ./VBoxLinuxAdditions.run
Laravel 5.3 让用户使用明文密码并登陆
虽然不推荐使用明文密码,但是我还是发一篇教程
使用的方法还是自定义Hash,只不过我们在处理中不进行hash运算即可,参考https://onlyke.com/html/829.html
首先,新建自定义的NonHasher
<?php namespace App\Libraries\Hashing; use Illuminate\Contracts\Hashing\Hasher as HasherContract; class NonHasher implements HasherContract{ /** * Hash the given value. * * @param string $value * @param array $options * @return string */ public function make($value, array $options = []){ return $value; } /** * Check the given plain value against a hash. * * @param string $value * @param string $hashedValue * @param array $options * @return bool */ public function check($value, $hashedValue, array $options = []){ if (strlen($hashedValue) === 0) { return false; } return strcmp($value,$hashedValue) == 0; } /** * Check if the given hash has been hashed using the given options. * * @param string $hashedValue * @param array $options * @return bool */ public function needsRehash($hashedValue, array $options = []){ if (strlen($hashedValue) === 0) { return false; } return $hashedValue; } }
然后,在AuthServiceProvider中注入
#app\Providers\AuthServiceProvider.php namespace App\Providers; use Auth; use Illuminate\Auth\EloquentUserProvider; use App\Libraries\Hashing\NonHasher; use Illuminate\Support\Facades\Gate; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider { /** * The policy mappings for the application. * * @var array */ protected $policies = [ 'App\Model' => 'App\Policies\ModelPolicy', ]; /** * Register any authentication / authorization services. * * @return void */ public function boot() { $this->registerPolicies(); //使用自定义的Hash来处理密码 Auth::provider('non', function($app, array $config) { return new EloquentUserProvider(new NonHasher,$config['model']); }); } }
当然,最后别忘了设置config\auth.php下面的providers中driver为你上面在Auth::provider中声明的名字
/* |-------------------------------------------------------------------------- | User Providers |-------------------------------------------------------------------------- | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | If you have multiple user tables or models you may configure multiple | sources which represent each model / table. These sources may then | be assigned to any extra authentication guards you have defined. | | Supported: "database", "eloquent" | */ 'providers' => [ 'users' => [ 'driver' => 'non', 'model' => App\User::class, ], // 'users' => [ // 'driver' => 'database', // 'table' => 'users', // ], ],
Laravel 5.3 使用自定义的哈希(Hash)函数来处理密码
为了兼容minecraft的authme密码hash方式,我们不能使用laravel自带的BcryptHash。所以我们需要对登录流程进行一些修改。
首先我们来看原来的BcryptHash是在哪里使用的
#vendor\laravel\framework\src\Illuminate\Auth\CreatesUserProviders.php /** * Create an instance of the Eloquent user provider. * * @param array $config * @return \Illuminate\Auth\EloquentUserProvider */ protected function createEloquentProvider($config) { return new EloquentUserProvider($this->app['hash'], $config['model']); }
这里我们发现当创建默认的EloquentUserProvider时,laravel自带hash,也就是Bcrypt被作为参数传递了,所以我们就要想办法让这里不使用自带hash,而在这里直接更改是不行的,因为这是laravel的源码,我们是不能修改的。
我们转而把注意力放在自定义UserProvider上,自定义之后我们当然就能使用自己的hash方式了。下面是一个例子(http://laravelacademy.org/post/5974.html)
#app\Providers\AuthServiceProvider.php <?php namespace App\Providers; use Illuminate\Support\Facades\Auth; use App\Extensions\RiakUserProvider; use Illuminate\Support\ServiceProvider; class AuthServiceProvider extends ServiceProvider { /** * Register any application authentication / authorization services. * * @return void */ public function boot() { $this->registerPolicies(); Auth::provider('riak', function($app, array $config) { // Return an instance of Illuminate\Contracts\Auth\UserProvider... return new RiakUserProvider($app->make('riak.connection')); }); } }
但是这时候我们发现,其实我们完全还可以在这里继续使用EloquentUserProvider,因为我们的目的只是更改hash方式,只需要在上面实例化EloquentUserProvider的地方,将我们自己的Hash类作为第一个参数传递进去就好了。
首先,我们先写好我们自己的Hash类,根据EloquentUserProvider的源码,我们发现我们的Hash类必须是Illuminate\Contracts\Hashing\Hasher契约的实现,契约的源码如下
interface Hasher { /** * Hash the given value. * * @param string $value * @param array $options * @return string */ public function make($value, array $options = []); /** * Check the given plain value against a hash. * * @param string $value * @param string $hashedValue * @param array $options * @return bool */ public function check($value, $hashedValue, array $options = []); /** * Check if the given hash has been hashed using the given options. * * @param string $hashedValue * @param array $options * @return bool */ public function needsRehash($hashedValue, array $options = []); }
我们只需要补全上面的方法,实现这个接口即可,下面是我们自定义的AuthmeHasher
namespace App\Libraries\Hashing; use Illuminate\Contracts\Hashing\Hasher as HasherContract; class AuthmeHasher implements HasherContract{ /** * Hash the given value. * * @param string $value * @param array $options * @return string */ public function make($value, array $options = []){ $p1 = '$SHA'; $p2 = str_random(16); $p3 = hash('sha256', hash('sha256', $value) . $p2); $hash = join('$',[$p1,$p2,$p3]); return $hash; } /** * Check the given plain value against a hash. * * @param string $value * @param string $hashedValue * @param array $options * @return bool */ public function check($value, $hashedValue, array $options = []){ if (strlen($hashedValue) === 0) { return false; } $parts = explode('$', $hashedValue); return count($parts) === 4 && $parts[3] === hash('sha256', hash('sha256', $value) . $parts[2]); } /** * Check if the given hash has been hashed using the given options. * * @param string $hashedValue * @param array $options * @return bool */ public function needsRehash($hashedValue, array $options = []){ if (strlen($hashedValue) === 0) { return false; } return $hashedValue; } }
这里由于不知道needsRehash方法该如何写,所以我直接返回了原先的hashedValue。具体这个文件的写法,我们也可以参考laravel默认的vendor\laravel\framework\src\Illuminate\Hashing\BcryptHasher.php
接下来就是最关键的部分了,我们将自己的AuthmeHash注入到EloquentUserProvider
#app\Providers\AuthServiceProvider.php namespace App\Providers; use Auth; use Illuminate\Auth\EloquentUserProvider; use App\Libraries\Hashing\AuthmeHasher; use Illuminate\Support\Facades\Gate; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider { /** * The policy mappings for the application. * * @var array */ protected $policies = [ 'App\Model' => 'App\Policies\ModelPolicy', ]; /** * Register any authentication / authorization services. * * @return void */ public function boot() { $this->registerPolicies(); //使用authme的Hash来处理密码 Auth::provider('authme', function($app, array $config) { return new EloquentUserProvider(new AuthmeHasher,$config['model']); }); } }
当然,最后别忘了设置config\auth.php下面的providers中driver为你上面在Auth::provider中声明的名字
/* |-------------------------------------------------------------------------- | User Providers |-------------------------------------------------------------------------- | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | If you have multiple user tables or models you may configure multiple | sources which represent each model / table. These sources may then | be assigned to any extra authentication guards you have defined. | | Supported: "database", "eloquent" | */ 'providers' => [ 'users' => [ 'driver' => 'authme', 'model' => App\User::class, ], // 'users' => [ // 'driver' => 'database', // 'table' => 'users', // ], ],
在最后还是说一句,学习Laravel阅读源码还是关键,文档的作用有的时候比较有局限性。本篇文章参考了http://blueve.me/archives/898的一些信息
为Ubuntu新创建用户创建默认.bashrc并自动加载
首先,su – 到新创建的用户
拷贝默认的.bashrc过来
cp /etc/skel/.bashrc ~/
然后创建.profile文件
vi ~/.profile
粘贴下面的内容
# ~/.profile: executed by Bourne-compatible login shells. if [ "$BASH" ]; then if [ -f ~/.bashrc ]; then . ~/.bashrc fi fi mesg n
想立即生效,执行下面命令
source ~/.profile
解决中国大陆在更新Chrome 显示Flash过期的问题
前几日,我把Chrome更新到了54.0.2840.71版本,更新后发现所有含有Flash的站点均被提示Flash版本过期(Shockwave flash 23.0.0.166)。而此时Chrome已经为最新版本,无法通过升级Chrome的方式来升级Flash,而由于墙的原因,按照官方指南,到chrome://components/中点击“检查是否有更新”并没有反应(其实我已经全局用ss翻墙了,但是不知道为什么依然没有作用)。
后来找到的解决方案如下:
到下面的地址下载最新版本的PPAPI类型的Flash插件并手动安装
第 4 步:从 Adobe 的网站安装 Flash Player
- 在计算机上打开 Chrome。
- 转至 https://get.adobe.com/cn/flashplayer/otherversions/。
- 在“第 1 步”下方,选择计算机的操作系统。
- 在“第 2 步”下方,选择列有“PPAPI”的选项。
- 点击立即下载,然后按照相应步骤安装 Adobe Flash Player。
安装完成后,重启Chrome。打开chrome://plugins/,发现Chrome已经自动识别最新版本
新版本Chrome已经可以自动识别我们手动安装的插件。如果你还想把Flash文件拷贝到Chrome中(以下环境为64位系统安装64位Chrome),关闭Chrome,打开运行,输入
%appdata%\..\Local\Google\Chrome\User Data\PepperFlash
打开后,按照上图的Flash版本,新建一个文件夹,比如这里是23.0.0.185,。然后把旧的文件夹删除。将C:\Windows\System32\Macromed\Flash目录里的manifest.json 和 pepflashplayer64_23_0_0_185.dll文件复制到你新建的那个目录里面,然后把pepflashplayer64_23_0_0_185.dll重命名为pepflashplayer.dll
不过,如果你是32位系统,用的32位Chrome,就到 C:\Windows\System32\Macromed\Flash 目录下找到 manifest.json 和 pepflashplayer32_23_0_0_185.dll 这样俩文件。如果你是64位系统,用的32位Chrome,就到 C:\Windows\SysWOW64\Macromed\Flash 目录下找到 manifest.json 和 pepflashplayer32_23_0_0_185.dll 这样俩文件。不要忘记对应dll改名为pepflashplayer.dll
复制完成后你就可以卸载我们刚才安装的Flash程序了
Ubuntu 编译安装shadowsocks-libev
编译安装shadowsocks-libev
shadowsocks-libev现在的默认分支为rm,clone的时候需要指定分支为master
git clone -b master https://github.com/shadowsocks/shadowsocks-libev.git apt-get install build-essential autoconf libtool libssl-dev libpcre3 libpcre3-dev ./configure --disable-documentation && make make install
当作为客户端使用时的配置文件
{ "server":"服务器ip", "server_port":服务器端口, "local_address":"127.0.0.1", "local_port":1080, "password":"密码", "timeout":300, "method":"chacha20", "fast_open":false, "workers":1 }
在Command Line Tools中使用ss代理
安装proxychains
apt-get install proxychains
编辑文件~/.proxychains/proxychains.conf
复制粘贴下面的内容
strict_chain proxy_dns remote_dns_subnet 224 tcp_read_time_out 15000 tcp_connect_time_out 8000 localnet 127.0.0.0/255.0.0.0 quiet_mode [ProxyList] socks5 127.0.0.1 1080
使用方法
proxychains curl https://www.google.com proxychains bash
Ubuntu通过gitolite快速部署git server并开启master分支网站代码自动部署
安装git和gitolite
首先,通过下面的命令安装git和gitolite
apt-get install git-core apt-get install gitolite
添加git用户组
adduser --system --group --shell /bin/bash --disabled-password git
配置密钥
接下来在本地机器生成ssh密钥,使用下面的命令
ssh-keygen -t rsa -C "[email protected]"
当然,如果你想为你的gitolite分配单独的密钥,可以使用下面的命令(生成名为git-admin的密钥)
ssh-keygen -C "[email protected]" -f ~/.ssh/git-admin
如果你使用了单独分配的密钥,你需要配置你的git在连接指定域名时使用不同的密钥,比如我们这里gitolite的管理域名是admin.xxx.com 。我们在刚才的.ssh文件夹新建config 文件(没有扩展名),内容如下
Host admin.xxx.com IdentityFile ~/.ssh/git-admin
这样就可以在连接admin.xxx.com的时候使用git-admin这组密钥了
初始化gitolite
下一步,将你的ssh公钥上传到服务器的某个位置,比如/tmp/git-admin.pub
然后切换到git用户,使用这个公钥初始化gitolite
su - git gl-setup /tmp/git-admin.pub
然后在持有私钥的机器管理gitolite即可,下面是clone命令,注意修改ip地址
git clone git@git_server_IP_address:gitolite-admin
关于gitolite的官方文档在这里:http://gitolite.com/gitolite/gitolite.html
自动部署
然后关于配置自动部署,首先我需要部署的网站目录权限为www-data:www-data
我把git用户添加到了www-data组中,通过后面权限设置为770保证网站和git都有足够的权限操作文件。使用下面的命令
usermod -a -G www-data git
然后网站目录,比如创建/home/nginx/xxx ,我们要把这个目录的用户组改成www-data并给予770权限,这样以后我们的git用户才能操作
然后我们切换到git用户,在/home/nginx/xxx 目录克隆本地库,使用下面的命令。注意clone后面最后有一个参数.
su - git git clone ~/repositories/xxx.git .
这样网站目录就初始化完成了,我们继续下面的操作(还是git用户的身份)
钩子文件创建在项目库的hooks文件夹~/repositories/xxx.git/hooks ,新建post-receive 文件,复制粘贴下面的内容,最后别忘了给予本脚本执行权限。就可以退出git用户身份了
#!/bin/bash while read oldrev newrev ref do branch=`echo $ref | cut -d/ -f3` echo "--- Current branch is : "$branch if [ "master" == "$branch" ]; then unset GIT_DIR NowPath=`pwd` echo "--- Now path is :"$NowPath DeployPath="/home/nginx/xxx" echo "--- Deploy path is :"$DeployPath cd $DeployPath echo "--- Go to deploy path" git add -A && git fetch origin && git reset --hard origin/master chmod -f -R 770 * chown -f -R git:www-data * echo "--- Deploy done" cd $NowPath echo "--- Fine" fi done exit 0
解释一下:
首先我们循环读取所有push的请求,当发现是push到master(也就是我们的部署分支)时,触发部署脚本,首先要清楚GIT_DIR环境变量,这样才能切换工作目录。然后我们切换到nginx的网站目录,使用git add -A && git fetch origin && git reset –hard origin/master 强制清除本地变化并更新到远程master分支。如果有网站自动生成的文件(比如用户上传的附件目录)不想被清空的,别忘了要写在.gitignore 文件里。当然网站生成的文件请确保权限在770以上,否则可能会导致git无权操作。在更新完远程master分支的代码后,更新文件权限为770,并将所有者改成www-data组(chmod使用末尾的*可以确保不会修改网站目录下.git这个隐藏目录内部的权限,同时-f用来屏蔽错误信息)
在编写本篇文章的时候感谢下面这位非常热心的博主解答我好多问题
https://argcv.com/articles/2078.c