CentOS7安装ffmpeg以及第三方依赖

序、简介

FFmpeg

  • 一个完整的跨平台解决方案,用于记录、转换和流化传输音频和视频的工具
  • 文档:https://www.ffmpeg.org/documentation.html
  • 官方网站:https://www.ffmpeg.org

这里记录 CentOS7 系统结合部分第三方依赖来源码编译安装 FFMPEG

在私人目录下创建一个新目录,将所有源代码放入:

1mkdir ~/ffmpeg_sources

一、NASM

NASM(The Netwide Assembler),是一款基于 80×86 和 x86-64 平台的汇编语言编译程序,其设计初衷是为了实现编译器程序跨平台和模块化的特性。NASM支持大量文件格式,包括 Linux,*BSM,a.out,ELF,COFF,Mach-O,Microsoft 16-bit OBJ,Win32 以及 Win64,同时也支持简单的二进制文件生成。

有两种方法:源码编译安装 或者 系统安装

系统安装:

这种方法需要联网状态,但是安装的 NSAM 可能会显示版本太低

sudo yum install nsam -y

源码编译安装:

cd ~/ffmpeg_sources
curl -O -L https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.bz2
tar -xjvf nasm-2.14.02.tar.bz2
cd nasm-2.14.02
./autogen.sh
./configure –prefix=”$HOME/ffmpeg_build” –bindir=”$HOME/bin”
make
make install

二、YASM(基于NASM,故装这个最好先装NASM)

YASM 是一个完全重写的 NASM 汇编,基于 NASM 开发的,有较好的优化,对于 NASM 中一些不合理的地方进行了修改。目前,支持 x86 和 AMD64 指令集。

有两种方法:源码编译安装 或者 系统安装

系统安装:

同样必须要联网状态,但是安装的 YASM 可能会显示版本太低,也有一个好处,就是顺便将YASM的依赖也一起安装了

sudo yum install yasm -y

源码编译安装:

cd ~/ffmpeg_sources
curl -O -L http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
tar -zxvf yasm-1.3.0.tar.gz
cd yasm-1.3.0
./configure –prefix=”$HOME/ffmpeg_build” –bindir=”$HOME/bin”
make
make install

三、libx264

x264 是一款免费的用于编码 H.264/MPEG-4 AVC 格式的视音频码流库。

官方网站:https://www.videolan.org/developers/x264.html

源码安装:libx264

cd ~/ffmpeg_sources
 git clone –depth 1 http://git.videolan.org/git/x264cd x264 (or) wget http://download.videolan.org/pub/videolan/x264/snapshots/last_x264.tar.bz2
tar -jxf last_x264.tar.bz2
cd x264-snapshot-20190530-2245-stable PKG_CONFIG_PATH=”$HOME/ffmpeg_build/lib/pkgconfig”
./configure –prefix=”$HOME/ffmpeg_build” –bindir=”$HOME/bin” –enable-static
make
make install

四、libx265

x265 是一款免费的用于编码 H.265/MPEG-H HEVC 格式的视音频码流库。

官方网站:https://www.videolan.org/developers/x265.html

源码安装:libx265

cd ~/ffmpeg_sources
 hg clone https://bitbucket.org/multicoreware/x265cd x265/build/linux(or)wget http://download.videolan.org/pub/videolan/x265/x265_3.0.tar.gz
tar -xvf x265_3.0.tar.gzcd x265_3.0/build/linux 
cmake -G “Unix Makefiles” -DCMAKE_INSTALL_PREFIX=”$HOME/ffmpeg_build” -DENABLE_SHARED:bool=off ../../source(or)./make-Makefiles.bash[ press “enter” motidy params & press C and press G ] makemake install

五、libfdk_acc

Fraunhofer FDK AAC(libfdk_acc),是一款不会提供在已编译的 FFMPEG 可执行包中的第三方依赖库,用于 AAC-LC 编码 和 HE-AAC(v1/2) 编码。所以需要在FFMPEG中加入相关包重编译。

源码安装:libfdk_aac

cd ~/ffmpeg_sources
git clone –depth 1 https://github.com/mstorsjo/fdk-aaccd fdk-aacautoreconf -fiv./configure –prefix=”$HOME/ffmpeg_build” –disable-sharedmakemake install

六、libmp3lame

LAME 是一款免费的+最好的 MP3 编码器,编码高品质 MP3 的最好也是唯一的选择。

源码安装:libmp3lame

cd ~/ffmpeg_sourcescurl -O -L http://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gztar -zxvf lame-3.100.tar.gzcd lame-3.100./configure –prefix=”$HOME/ffmpeg_build” –bindir=”$HOME/bin” –disable-shared –enable-nasmmakemake install

七、libopus

Opus 是一种声音编码格式。其前身是 celt 编码器。在当今的有损音频格式中,拥有众多不同编码器的 AAC 格式打败了颇有潜力的 Musepack、Vorbis 等格式。在低码率下 Opus 完胜 HE-AAC。

源码安装:libopus

cd ~/ffmpeg_sourcescurl -O -L https://ftp.osuosl.org/pub/xiph/releases/opus/opus-1.3.1.tar.gztar -zxvf opus-1.3.1.tar.gzcd opus-1.3.1./configure –prefix=”$HOME/ffmpeg_build” –disable-sharedmakemake install

八、libogg

Ogg(oggVorbis) 是一种音频压缩格式,类似于 MP3 等音乐格式。Ogg是完全免费、开放、没有专利限制的。其文件拓展名为”.ogg”。

源码安装:libogg

cd ~/ffmpeg_sourcescurl -O -L https://ftp.osuosl.org/pub/xiph/releases/ogg/libogg-1.3.3.tar.gzcd libogg-1.3.3./configure –prefix=”$HOME/ffmpeg_build” –disable-sharedmakemake install

九、libvorbis

同为为 FFMPEG 提供 oggVorbis 文件格式的压缩编码。

源码安装:libvorbis

cd ~/ffmpeg_sourcescurl -O -L https://ftp.osuosl.org/pub/xiph/releases/vorbis/libvorbis-1.3.6.tar.gztar -zxvf libvorbis-1.3.6.tar.gzcd libvorbis-1.3.6./configure –prefix=”$HOME/ffmpeg_build” –with-ogg=”$HOME/ffmpeg_build” –disable-sharedmakemake install

十、speex

Speex 是一款开源免费的、无专利保护的、针对语音设计的音频压缩格式。Speex 编解码器已经被 Opus 编解码器淘汰,但还是可以继续使用。虽然 Opus 比 Speex 好,但 Opus 只支持编码和解码,不支持噪音抑制、声学回音消除等其他处理功能。

(这里并没有将Speex加入FFMPEG编译中,但可以支持的)

cd ~/ffmpeg_sourcescurl -O -L https://ftp.osuosl.org/pub/xiph/releases/speex/speex-1.2.0.tar.gz

十一、libvpx

libvpx 是一款开源的 VP8 编码解码器。为 FFMPEG 提供 VP8 编码解码的支持。如编码YUV->VP8(On2 VP8)。

源码安装:libvpx

cd ~/ffmpeg_sourceswget https://github.com/webmproject/libvpx/archive/v1.7.0.tar.gztar -zxvf v1.7.0.tar.gzmv libvpx-1.7.0 libvpxcd libvpx./configure –prefix=”$HOME/ffmpeg_build” –with-ogg=”$HOME/ffmpeg_build” –disable-sharedmakemake install

十二、FFmpeg

cd ~/ffmpeg_sourcescurl -O -L https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2tar -xjvf ffmpeg-snapshot.tar.bz2cd ffmpegPATH=”$HOME/bin:$PATH” PKG_CONFIG_PATH=”$HOME/ffmpeg_build/lib/pkgconfig” ./configure \  –prefix=”$HOME/ffmpeg_build” \  –pkg-config-flags=”–static” \  –extra-cflags=”-I$HOME/ffmpeg_build/include” \  –extra-ldflags=”-L$HOME/ffmpeg_build/lib” \  –extra-libs=-lpthread \  –extra-libs=-lm \  –bindir=”$HOME/bin” \  –enable-gpl \  –enable-libfdk_aac \  –enable-libfreetype \  –enable-libmp3lame \  –enable-libopus \  –enable-libvorbis \  –enable-libvpx \  –enable-libx264 \  –enable-libx265 \  –enable-nonfreemake -j8make install

CENTOS7 GNOME 安装中文支持

网上的文章都是互相抄的,很多都不适用。这个亲测成功了。

先安装字体

yum  groupinstall  “fonts”

然后按照以下步骤:

1、查看当前显示格式及编码

echo $LANG	//一般默认显示为en_US.UTF-8

2、查看是否安装中文字体

locale -a | grep 'zh_CN*' //查看是否有zh_CN.UTF-8

3、安装中文字体(如果没有)

yum install kde-l10n-Chinese

4、修改配置文件

vi /etc/locale.conf	//修改配置文件

内容为:

LANG=“ZH_CN.utf-8”

保存

5、修改启动文件

由于系统重启后会自动加载该文件,会覆盖掉配置文件

vi /etc /etc/profile.d/lang.sh

内容为:

修改为:

这样重启后不会失效

6、重启linux

reboot

Yii2 basic, authorization and registration via the database

A simple example of fine-tuning Yii2 basic for authorization via the database, adding registration and resetting the password.

原文地址: https://devreadwrite.com/posts/yii2-basic-authorization-and-registration-via-the-database

To begin with, yii2 basic must already be installed. How to do this is described here: Short instruction. How to install Yii 2 basic.

Configure the connection to the database in the file /config/db.php and proceed.

Add authorization on the site in Yii2 basic

Open the console and add the migration to create the User table

yii migrate/create create_user_table

Open the file with the migration /migration/m000000_000000_create_user_table.php and add the code for creating the migration, we will not reinvent the wheel, and we will do the same as in the version advanced:

<?php use yii\db\Migration; class m000000_000000_create_user_table extends Migration{     public function up()    {        $tableOptions = null;         if ($this->db->driverName === 'mysql') {            $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';        }         $this->createTable('user', [            'id' => $this->primaryKey(),            'username' => $this->string()->notNull()->unique(),            'auth_key' => $this->string(32)->notNull(),            'password_hash' => $this->string()->notNull(),            'password_reset_token' => $this->string()->unique(),            'email' => $this->string()->notNull()->unique(),            'status' => $this->smallInteger()->notNull()->defaultValue(10),            'created_at' => $this->integer()->notNull(),            'updated_at' => $this->integer()->notNull(),        ], $tableOptions);    }     public function down()    {        $this->dropTable('user');    } }

After saving the edits in the migration file (copy only the methods code up() and down()), execute it in the console:

yii migrate

Edit model /models/User.php:

<?php namespace app\models; use Yii;use yii\base\NotSupportedException;use yii\behaviors\TimestampBehavior;use yii\db\ActiveRecord;use yii\web\IdentityInterface; /** * User model * * @property integer $id * @property string $username * @property string $password_hash * @property string $password_reset_token * @property string $email * @property string $auth_key * @property integer $status * @property integer $created_at * @property integer $updated_at * @property string $password write-only password */class User extends ActiveRecord implements IdentityInterface{    const STATUS_DELETED = 0;    const STATUS_ACTIVE = 10;     /**     * @inheritdoc     */    public static function tableName()    {        return '{{%user}}';    }     /**     * @inheritdoc     */    public function behaviors()    {        return [            TimestampBehavior::className(),        ];    }     /**     * @inheritdoc     */    public function rules()    {        return [            ['status', 'default', 'value' => self::STATUS_ACTIVE],            ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],        ];    }     /**     * @inheritdoc     */    public static function findIdentity($id)    {        return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);    }     /**     * @inheritdoc     */    public static function findIdentityByAccessToken($token, $type = null)    {        throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');    }     /**     * Finds user by username     *     * @param string $username     * @return static|null     */    public static function findByUsername($username)    {        return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);    }     /**     * @inheritdoc     */    public function getId()    {        return $this->getPrimaryKey();    }     /**     * @inheritdoc     */    public function getAuthKey()    {        return $this->auth_key;    }     /**     * @inheritdoc     */    public function validateAuthKey($authKey)    {        return $this->getAuthKey() === $authKey;    }     /**     * Validates password     *     * @param string $password password to validate     * @return bool if password provided is valid for current user     */    public function validatePassword($password)    {        return Yii::$app->security->validatePassword($password, $this->password_hash);    }     /**     * Generates password hash from password and sets it to the model     *     * @param string $password     */    public function setPassword($password)    {        $this->password_hash = Yii::$app->security->generatePasswordHash($password);    }     /**     * Generates "remember me" authentication key     */    public function generateAuthKey()    {        $this->auth_key = Yii::$app->security->generateRandomString();    } }

Authorization is ready, now we will add a user to check authorization. Open the controller /controllers/SiteController.php and add the action to the end of the controller which will help us add the user:

public function actionAddAdmin() {    $model = User::find()->where(['username' => 'admin'])->one();    if (empty($model)) {        $user = new User();        $user->username = 'admin';        $user->email = 'admin@devreadwrite.com';        $user->setPassword('admin');        $user->generateAuthKey();        if ($user->save()) {            echo 'good';        }    }}

Run the action: site.com/web/index.php?r=site/add-admin and check the authorization site.com/web/index.php?r=site/login

After successful authorization, the AddAdmin action can be deleted as a useless item.

If you only need authorization via a database in Yii2 basic, then you can end this. If in addition to authorizing through the database on the site you need to add registration and password recovery, then continue.

Add registration to the site in Yii2 basic

First, create a model for the registration forms, for this you need to create a file /models/SignupForm.php with the following content:

<?ph namespace app\models; use Yii;use yii\base\Model; /** * Signup form */class SignupForm extends Model{     public $username;    public $email;    public $password;     /**     * @inheritdoc     */    public function rules()    {        return [            ['username', 'trim'],            ['username', 'required'],            ['username', 'unique', 'targetClass' => '\app\models\User', 'message' => 'This username has already been taken.'],            ['username', 'string', 'min' => 2, 'max' => 255],            ['email', 'trim'],            ['email', 'required'],            ['email', 'email'],            ['email', 'string', 'max' => 255],            ['email', 'unique', 'targetClass' => '\app\models\User', 'message' => 'This email address has already been taken.'],            ['password', 'required'],            ['password', 'string', 'min' => 6],        ];    }     /**     * Signs user up.     *     * @return User|null the saved model or null if saving fails     */    public function signup()    {         if (!$this->validate()) {            return null;        }         $user = new User();        $user->username = $this->username;        $user->email = $this->email;        $user->setPassword($this->password);        $user->generateAuthKey();        return $user->save() ? $user : null;    } }

Next, in /controllers/SiteController.php in use, add registration model SignupForm and action signup:

<?php namespace app\controllers; //... use app\models\LoginForm;use app\models\ContactForm;use app\models\SignupForm; class SiteController extends Controller{     //...     public function actionSignup()    {        $model = new SignupForm();         if ($model->load(Yii::$app->request->post())) {            if ($user = $model->signup()) {                if (Yii::$app->getUser()->login($user)) {                    return $this->goHome();                }            }        }         return $this->render('signup', [            'model' => $model,        ]);    } }

Next, you need to add a view for registration, add a file /views/site/signup.php with the following content:

<?php use yii\helpers\Html;use yii\bootstrap\ActiveForm; $this->title = 'Signup';$this->params['breadcrumbs'][] = $this->title;?><div class="site-signup">    <h1><?= Html::encode($this->title) ?></h1>    <p>Please fill out the following fields to signup:</p>    <div class="row">        <div class="col-lg-5">             <?php $form = ActiveForm::begin(['id' => 'form-signup']); ?>                <?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>                <?= $form->field($model, 'email') ?>                <?= $form->field($model, 'password')->passwordInput() ?>                <div class="form-group">                    <?= Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>                </div>            <?php ActiveForm::end(); ?>         </div>    </div></div>

And the last thing you need to do is add registration to the menu. Open the file /views/layouts/main.php find the menu widget and add the registration item, after which the widget with the following form:

<?php NavBar::begin([    'brandLabel' => 'My Company',    'brandUrl' => Yii::$app->homeUrl,    'options' => [        'class' => 'navbar-inverse navbar-fixed-top',    ],]); echo Nav::widget([    'options' => ['class' => 'navbar-nav navbar-right'],    'items' => [        ['label' => 'Home', 'url' => ['/site/index']],        ['label' => 'About', 'url' => ['/site/about']],        ['label' => 'Contact', 'url' => ['/site/contact']],        Yii::$app->user->isGuest ? (            ['label' => 'Login', 'url' => ['/site/login']]        ) : (            '<li>'            . Html::beginForm(['/site/logout'], 'post')            . Html::submitButton(                'Logout (' . Yii::$app->user->identity->username . ')',                ['class' => 'btn btn-link logout']            )            . Html::endForm()            . '</li>'        )    ],]); NavBar::end();?>

Full code:

<?php NavBar::begin([    'brandLabel' => 'My Company',    'brandUrl' => Yii::$app->homeUrl,    'options' => [        'class' => 'navbar-inverse navbar-fixed-top',    ],]); $menuItems = [    ['label' => 'Home', 'url' => ['/site/index']],    ['label' => 'About', 'url' => ['/site/about']],    ['label' => 'Contact', 'url' => ['/site/contact']],]; if (Yii::$app->user->isGuest) {    $menuItems[] = ['label' => 'Signup', 'url' => ['/site/signup']];    $menuItems[] = ['label' => 'Login', 'url' => ['/site/login']];} else {    $menuItems[] = '<li>'        . Html::beginForm(['/site/logout'], 'post')        . Html::submitButton(            'Logout (' . Yii::$app->user->identity->username . ')',            ['class' => 'btn btn-link logout']        )        . Html::endForm()        . '</li>';} echo Nav::widget([    'options' => ['class' => 'navbar-nav navbar-right'],    'items' => $menuItems,]); NavBar::end();?>

Now we have registration and authorization in Yii2 basic.

For full functionality only need to do reset and password recovery.

Add password recovery on the site in Yii2 basic

First, you need to modify the /models/User.php model and add several methods to create and reset the token of password:

public static function findByPasswordResetToken($token){    if (!static::isPasswordResetTokenValid($token)) {        return null;    }    return static::findOne([        'password_reset_token' => $token,        'status' => self::STATUS_ACTIVE,    ]);}public static function isPasswordResetTokenValid($token){    if (empty($token)) {        return false;    }    $timestamp = (int) substr($token, strrpos($token, '_') + 1);    $expire = Yii::$app->params['user.passwordResetTokenExpire'];    return $timestamp + $expire >= time();}public function generatePasswordResetToken(){    $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();}public function removePasswordResetToken(){    $this->password_reset_token = null;}

As a result, the model /models/User.php will look like this:

<?php namespace app\models; use Yii;use yii\base\NotSupportedException;use yii\behaviors\TimestampBehavior;use yii\db\ActiveRecord;use yii\web\IdentityInterface; class User extends ActiveRecord implements IdentityInterface{    const STATUS_DELETED = 0;    const STATUS_ACTIVE = 10;     public static function tableName()    {        return '{{%user}}';    }     public function behaviors()    {        return [            TimestampBehavior::className(),        ];    }     public function rules()    {        return [            ['status', 'default', 'value' => self::STATUS_ACTIVE],            ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],        ];    }     public static function findIdentity($id)    {        return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);    }     public static function findIdentityByAccessToken($token, $type = null)    {        throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');    }     public static function findByUsername($username)    {        return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);    }     public static function findByPasswordResetToken($token)    {         if (!static::isPasswordResetTokenValid($token)) {            return null;        }         return static::findOne([            'password_reset_token' => $token,            'status' => self::STATUS_ACTIVE,        ]);    }     public static function isPasswordResetTokenValid($token)    {         if (empty($token)) {            return false;        }         $timestamp = (int) substr($token, strrpos($token, '_') + 1);        $expire = Yii::$app->params['user.passwordResetTokenExpire'];        return $timestamp + $expire >= time();    }     public function getId()    {        return $this->getPrimaryKey();    }     public function getAuthKey()    {        return $this->auth_key;    }     public function validateAuthKey($authKey)    {        return $this->getAuthKey() === $authKey;    }     public function validatePassword($password)    {        return Yii::$app->security->validatePassword($password, $this->password_hash);    }     public function setPassword($password)    {        $this->password_hash = Yii::$app->security->generatePasswordHash($password);    }     public function generateAuthKey()    {        $this->auth_key = Yii::$app->security->generateRandomString();    }     public function generatePasswordResetToken()    {        $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();    }     public function removePasswordResetToken()    {        $this->password_reset_token = null;    } }

The method of checking token of password reset isPasswordResetTokenValid uses the variable user.passwordResetTokenExpire to reset password token, it must be specified in the file /congif/params.php:

<?phpreturn [    'adminEmail' => 'admin@example.com',    'user.passwordResetTokenExpire' => 3600,];

Next, you must add the request form model to change the password and the password change form model. Total 2 models. First, we’ll add the model of the request form to change the password /models/PasswordResetRequestForm.php with the following content:

<?php namespace app\models; use Yii;use yii\base\Model; /** * Password reset request form */class PasswordResetRequestForm extends Model{    public $email;     /**     * @inheritdoc     */    public function rules()    {        return [            ['email', 'trim'],            ['email', 'required'],            ['email', 'email'],            ['email', 'exist',                'targetClass' => '\app\models\User',                'filter' => ['status' => User::STATUS_ACTIVE],                'message' => 'There is no user with such email.'            ],        ];    }     /**     * Sends an email with a link, for resetting the password.     *     * @return bool whether the email was send     */    public function sendEmail()    {        /* @var $user User */        $user = User::findOne([            'status' => User::STATUS_ACTIVE,            'email' => $this->email,        ]);         if (!$user) {            return false;        }         if (!User::isPasswordResetTokenValid($user->password_reset_token)) {            $user->generatePasswordResetToken();            if (!$user->save()) {                return false;            }        }         return Yii::$app            ->mailer            ->compose(                ['html' => 'passwordResetToken-html', 'text' => 'passwordResetToken-text'],                ['user' => $user]            )            ->setFrom([Yii::$app->params['supportEmail'] => Yii::$app->name . ' robot'])            ->setTo($this->email)            ->setSubject('Password reset for ' . Yii::$app->name)            ->send();    } }

The model will send a confirmation to email for the password change. For this, it uses 2 layouts (html and text), we already have html, we need to add text. To do this, create a file /mail/layouts/text.php With the following content:

<?phpuse yii\helpers\Html;?><?php $this->beginPage() ?><?php $this->beginBody() ?><?= $content ?><?php $this->endBody() ?><?php $this->endPage() ?>

Also it is necessary to create 2 representations of the letter (html and text version). We will create an html version of the mail view, for this we create a file /mail/passwordResetToken-html.php with the following content:

<?php use yii\helpers\Html; $resetLink = Yii::$app->urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]);?> <div class="password-reset">    <p>Hello <?= Html::encode($user->username) ?>,</p>    <p>Follow the link below to reset your password:</p>    <p><?= Html::a(Html::encode($resetLink), $resetLink) ?></p></div>

And the view for text version /mail/passwordResetToken-text.php:

<?php$resetLink = Yii::$app->urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]);?>Hello <?= $user->username ?>,Follow the link below to reset your password:<?= $resetLink ?>

Model indicate as sender of e-mail from the parameter supportEmail, it must also be added. To do this, open the file /config/params.php for editing and add the element supportEmail to the array, you will end up with the following:

<?php return [    'adminEmail' => 'admin@devreadwrite.com',    'user.passwordResetTokenExpire' => 3600,    'supportEmail' => 'robot@devreadwrite.com'];

Next, the model for the form of password change /models/ResetPasswordForm.php with the following content:

<?php namespace app\models; use yii\base\Model;use yii\base\InvalidParamException; /** * Password reset form */class ResetPasswordForm extends Model{     public $password;     /**     * @var \app\models\User     */    private $_user;     /**     * Creates a form model given a token.     *     * @param string $token     * @param array $config name-value pairs that will be used to initialize the object properties     * @throws \yii\base\InvalidParamException if token is empty or not valid     */    public function __construct($token, $config = [])    {        if (empty($token) || !is_string($token)) {            throw new InvalidParamException('Password reset token cannot be blank.');        }         $this->_user = User::findByPasswordResetToken($token);         if (!$this->_user) {            throw new InvalidParamException('Wrong password reset token.');        }         parent::__construct($config);    }     /**     * @inheritdoc     */    public function rules()    {        return [            ['password', 'required'],            ['password', 'string', 'min' => 6],        ];    }     /**     * Resets password.     *     * @return bool if password was reset.     */    public function resetPassword()    {        $user = $this->_user;        $user->setPassword($this->password);        $user->removePasswordResetToken();        return $user->save(false);    } }

Now we add actions to work with the models described above. Open the controller /controllers/SiteController.php in use add the created models and 2 actions (actionRequestPasswordReset and actionResetPassword):

<?php namespace app\controllers; //... use app\models\SignupForm;use app\models\PasswordResetRequestForm;use app\models\ResetPasswordForm; class SiteController extends Controller{     //...     /**     * Requests password reset.     *     * @return mixed     */    public function actionRequestPasswordReset()    {        $model = new PasswordResetRequestForm();         if ($model->load(Yii::$app->request->post()) && $model->validate()) {             if ($model->sendEmail()) {                Yii::$app->session->setFlash('success', 'Check your email for further instructions.');                return $this->goHome();            } else {                Yii::$app->session->setFlash('error', 'Sorry, we are unable to reset password for email provided.');            }         }         return $this->render('requestPasswordResetToken', [            'model' => $model,        ]);    }     /**     * Resets password.     *     * @param string $token     * @return mixed     * @throws BadRequestHttpException     */    public function actionResetPassword($token)    {        try {            $model = new ResetPasswordForm($token);        } catch (InvalidParamException $e) {            throw new BadRequestHttpException($e->getMessage());        }         if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) {            Yii::$app->session->setFlash('success', 'New password was saved.');            return $this->goHome();        }         return $this->render('resetPassword', [            'model' => $model,      } }

Next, for these two actions, you need to add views, start with the request form to change the password /views/site/passwordResetRequestForm.php:

<?php use yii\helpers\Html;use yii\bootstrap\ActiveForm; $this->title = 'Request password reset';$this->params['breadcrumbs'][] = $this->title;?> <div class="site-request-password-reset">    <h1><?= Html::encode($this->title) ?></h1>    <p>Please fill out your email. A link to reset password will be sent there.</p>    <div class="row">        <div class="col-lg-5">             <?php $form = ActiveForm::begin(['id' => 'request-password-reset-form']); ?>                <?= $form->field($model, 'email')->textInput(['autofocus' => true]) ?>                <div class="form-group">                    <?= Html::submitButton('Send', ['class' => 'btn btn-primary']) ?>                </div>            <?php ActiveForm::end(); ?>         </div>    </div></div>

And the view for the password change form /views/site/resetPasswordForm.php:

<?php use yii\helpers\Html;use yii\bootstrap\ActiveForm; $this->title = 'Reset password';$this->params['breadcrumbs'][] = $this->title;?> <div class="site-reset-password">    <h1><?= Html::encode($this->title) ?></h1>    <p>Please choose your new password:</p>    <div class="row">        <div class="col-lg-5">             <?php $form = ActiveForm::begin(['id' => 'reset-password-form']); ?>                <?= $form->field($model, 'password')->passwordInput(['autofocus' => true]) ?>                <div class="form-group">                    <?= Html::submitButton('Save', ['class' => 'btn btn-primary']) ?>                </div>            <?php ActiveForm::end(); ?>         </div>    </div></div>

The final touch, add a link to reset the password in the authorization form view, to do this, open the file /views/site/login.php add a link to reset password:

<div>    If you forgot your password you can <?= Html::a('reset it', ['site/request-password-reset']) ?>.</div>

As a result, the view of authorization on the site will look like this:

<?php use yii\helpers\Html;use yii\bootstrap\ActiveForm; $this->title = 'Login';$this->params['breadcrumbs'][] = $this->title;?> <div class="site-login">    <h1><?= Html::encode($this->title) ?></h1>    <p>Please fill out the following fields to login:</p>     <?php $form = ActiveForm::begin([        'id' => 'login-form',        'layout' => 'horizontal',        'fieldConfig' => [            'template' => "{label}\n<div class=\"col-lg-3\">{input}</div>\n<div class=\"col-lg-8\">{error}</div>",            'labelOptions' => ['class' => 'col-lg-1 control-label'],        ],    ]); ?>        <?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>        <?= $form->field($model, 'password')->passwordInput() ?>        <?= $form->field($model, 'rememberMe')->checkbox([            'template' => "<div class=\"col-lg-offset-1 col-lg-3\">{input} {label}</div>\n<div class=\"col-lg-8\">{error}</div>",        ]) ?>        <div style="color:#999;margin:1em 0">            If you forgot your password you can <?= Html::a('reset it', ['site/request-password-reset']) ?>.        </div>        <div class="form-group">            <div class="col-lg-offset-1 col-lg-11">                <?= Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>            </div>        </div>    <?php ActiveForm::end(); ?> </div>

As a result, we got a full functionality of authorization through the database, registration and reset of password in Yii2 basic using the functionality of the template of Yii2 advanced.

Authorization in Yii2 by e-mail instead of username

For authorization on the site, I prefer using the user’s e-mail as a login instead of a nickname, by default, yii2 uses a nickname as the login. To fix this is quite simple.

Let’s start with the /models/User.php model and add the findByEmail method to search for the user by e-mail:

public static function findByEmail($email){    return static::findOne(['email' => $email, 'status' => self::STATUS_ACTIVE]);}

Next, in the model /models/LoginForm.php change the $username property to $email in the rules method, add e-mail handling of rule [[’email’], ’email’] and in the getUser () method, change the User::findByUsername($this->username) to User::findByEmail($this->email), this is what you get:

<?php namespace app\models; use Yii;use yii\base\Model; /** * LoginForm is the model behind the login form. * * @property User|null $user This property is read-only. * */class LoginForm extends Model{    public $email;    public $password;    public $rememberMe = true;    private $_user = false;     /**     * @return array the validation rules.     */    public function rules()    {        return [            // username and password are both required            [['email', 'password'], 'required'],            [['email'], 'email'],            // rememberMe must be a boolean value            ['rememberMe', 'boolean'],            // password is validated by validatePassword()            ['password', 'validatePassword'],        ];    }     /**     * Validates the password.     * This method serves as the inline validation for password.     *     * @param string $attribute the attribute currently being validated     * @param array $params the additional name-value pairs given in the rule     */    public function validatePassword($attribute, $params)    {         if (!$this->hasErrors()) {             $user = $this->getUser();             if (!$user || !$user->validatePassword($this->password)) {                $this->addError($attribute, 'Incorrect username or password.');            }         }     }     /**     * Logs in a user using the provided username and password.     * @return bool whether the user is logged in successfully     */    public function login()    {        if ($this->validate()) {            return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);        }        return false;    }     /**     * Finds user by [[email]]     *     * @return User|null     */    public function getUser()    {        if ($this->_user === false) {            $this->_user = User::findByEmail($this->email);        }        return $this->_user;    } }

Finally, in the /views/site/login.php view, change the username field to email:

<?= $form->field($model, 'email')->textInput(['autofocus' => true]) ?>

All source code is available on github: https://github.com/egor/yii2-basic-auth-through-db.

Article source: https://кодер.укр/записи/yii2-basic-авторизация-и-регистрация-через-бд.

Python3—UnicodeEncodeError ‘ascii’ codec can’t encode characters in position 0-1

环境

>>> import sys >>> print(sys.version) '3.6.0 |Anaconda 4.3.1 (64-bit)| (default, Dec 23 2016, 12:22:00) \n[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]'
  • 1
  • 2
  • 3

问题描述

今天在使用python3的时候,报错信息

Traceback (most recent call last): File "tmp.py", line 3, in <module> print(a) UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
  • 1
  • 2
  • 3
  • 4

报错代码可简化为

a = b'\xe5\x94\xb1\xe6\xad\x8c' a = a.decode("utf-8") print(a)
  • 1
  • 2
  • 3

问题分析

本节介绍问题的分析过程,如果想看解决办法,可以直接看一下节。

网上解释

网上给出的解释:错误的使用decode和encode方法会出现这种异常。例如使用decode方法将Unicode字符串转化的时候:

s = u'中文' s.decode('utf-8') print s
  • 1
  • 2
  • 3

但是将这个例子放到python3环境中,会报错

Traceback (most recent call last): File "tmp_2.py", line 4, in <module> s.decode('utf-8') AttributeError: 'str' object has no attribute 'decode'
  • 1
  • 2
  • 3
  • 4

熟悉python历史的朋友会知道,为了解决编码问题,在python3中,所有的字符串都是使用Unicode编码,统一使用str类型来保存,而str类型没有decode方法,所以网上给出的方向并不适合我的问题。

字符编码

为了确定是否是字符编码的问题,我换了一台python3机器,测试了一下

>>>a = b'\xe5\x94\xb1\xe6\xad\x8c' >>>a = a.decode("utf-8") >>>print(a) 唱歌
  • 1
  • 2
  • 3
  • 4

完全没有问题,正常输出,排除字符编码和代码失误。

输出

既然字符编码、代码都没有错,那么问题肯定出在print上面。这时我开始关注错误信息中的ascii。因为在一般python3环境中,输出时会将Unicode转化为utf-8。为了解开这个疑惑,查看了输出编码

>>>import sys >>>sys.stdout.encoding 'ANSI_X3.4-1968'
  • 1
  • 2
  • 3

竟然是ANSI_X3.4-1968,所以任何中文都会报错。哈哈,终于定位问题啦。

解决方案

定位问题后,解决办法就很简单啦,有两种方法

运行python的时候加上PYTHONIOENCODING=utf-8,即

PYTHONIOENCODING=utf-8 python your_script.py
  • 1
  • 重新定义标准输出

标准输出的定义如下

sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach())
  • 1

打印日志的方法

sys.stdout.write("Your content....")
  • 1

总结

通过分析这个问题,进一步加深了对python3的了解。另外,希望各位看官批评指正!!

在CentOS 7上安装Python3

This tutorial will guide you through installing Python 3 on a CentOS 7 system using the Software Collections (SCL) alongside the distribution default Python version 2.7. We will also show you how to create a Python virtual environment.

Python is one of the most popular programming languages in the world. With its simple and easy to learn syntax Python is a great choice for beginners and experienced developers. Python is a quite versatile programming language, you can use it to do almost anything you want, write small scripts, build games, develop websites, create machine learning algorithms, analyze data and more.

Many popular applications and websites including YouTube, DropBox, Reddit, Quora, Instagram, Pinterest have been developed using Python.

While Python 2 is well-supported and active, Python 3 is considered to be the present and future of the language.

Enable Software Collections (SCL)

Software Collections, also known as SCL is a community project that allows you to build, install, and use multiple versions of software on the same system, without affecting system default packages. By enabling Software Collections you will gain access to the newer versions of programming languages and services which are not available in the core repositories.

 

CentOS 7 ships with Python 2.7.5 which is a critical part of the CentOS base system. SCL will allow you to install newer versions of python 3.x alongside the default python v2.7.5 so that system tools such as yum will continue to work properly.

In order to enable SCL we need to install the CentOS SCL release file. It is part of the CentOS extras repository and can be installed by running the following command:

 

sudo yum install centos-release-scl

Copy

Installing Python 3 on CentOS 7

Now that we have access to the SCL repository we can install any Python 3.x version we need. Currently, the following Python 3 collections are available:

  • Python 3.3
  • Python 3.4
  • Python 3.5
  • Python 3.6

In this tutorial we will install Python 3.6 which is the latest version available at the time of writing. To do so type the following command on your CentOS 7 terminal:

sudo yum install rh-python36

Copy

Using Python 3

After the package rh-python36 is installed, check the Python version by typing:

python --version

Copy

Python 2.7.5

Copy

You will notice that Python 2.7 is the default Python version in your current shell.

To access Python 3.6 you need to launch a new shell instance using the Software Collection scl tool:

 

scl enable rh-python36 bash

Copy

What the command above does is calling the script /opt/rh/rh-python36/enable which changes the shell environment variables.

If you check the Python version again, you’ll notice that Python 3.6 is the default version in your current shell now.

python --version

Copy

Python 3.6.3

Copy

It is important to point out that Python 3.6 is set as the default Python version only in this shell session. If you exit the session or open a new session from another terminal Python 2.7 will be the default Python version.

Installing Development Tools

Development tools are required for building Python modules, you can install the necessary tools and libraries by typing:

 

sudo yum groupinstall 'Development Tools'

Copy

Creating a Virtual Environment

Python Virtual Environments allows you to install Python modules in an isolated location for a specific project, rather than being installed globally. This way you do not have to worry about affecting other Python projects.

The preferred way to create a new virtual environment in Python 3 is by executing the venv command.

Let’s say we want to create a new Python 3 project called my_new_project inside our user home directory and matching virtual environment.

 

First, create the project directory and switch to it:

mkdir ~/my_new_projectcd ~/my_new_project

Copy

Activate Python 3.6 using the scl tool:

scl enable rh-python36 bash

Copy

From inside the project root run the following command to create a virtual environment named my_project_venv:

 

python -m venv my_project_venv

Copy

To use the virtual environment first we need to activate it by typing:

source my_project_venv/bin/activate

Copy

After activating the environment, the shell prompt will be prefixed with the name of the environment:

(my_project_venv) user@host:~/my_new_project$

Copy

Starting with Python 3.4, when creating virtual environments pip, the package manager for Python is installed by default.

Conclusion

You should now have Python 3 programming environment setup on your CentOS 7 machine and you can start developing your Python 3 project.

 

You can also read about how to Install Odoo 11 on CentOS 7 and see an example of how to use Python 3 virtual environment to run Python software on a CentOS 7 server.

在 CentOS 7 / RHEL 7 安装 Gnome GUI

Linux admins spend most of their time on working in a terminal; there are some who like to work on GUI instead of a terminal. By default, CentOS 7 installed as the minimal server, and user intervention is required to change the installation type. This guide will help you to install GUI on CentOS 7 on the top of the minimal server installation.

Before installing GUI, make a Local Yum Repository to avoid downloading packages from the internet.

READ: How to Configure YUM repository on CentOS 7 / RHEL 7

Optional: Run the following command to list down the available package groups for CentOS 7.

# yum group list

Output:

Loaded plugins: fastestmirror
There is no installed groups file.
Maybe run: yum groups mark convert (see man yum)
Loading mirror speeds from cached hostfile
Available Environment Groups:
 Minimal Install
 Compute Node
 Infrastructure Server
 File and Print Server
 Basic Web Server
 Virtualization Host
 Server with GUI
 GNOME Desktop
 KDE Plasma Workspaces
 Development and Creative Workstation
Available Groups:
 Compatibility Libraries
 Console Internet Tools
 Development Tools
 Graphical Administration Tools
 Legacy UNIX Compatibility
 Scientific Support
 Security Tools
 Smart Card Support
 System Administration Tools
 System Management
Done

 

Step 1: Install Gnome GUI packages using the YUM command.

 

CentOS 7:

# yum groupinstall "GNOME Desktop" "Graphical Administration Tools"

RHEL 7:

# yum groupinstall "Server with GUI"

Step 2: Enable GUI on system startup. In CentOS 7 / RHEL 7,  systemd uses “targets” instead of runlevel. The /etc/inittabfile is no more used to change run levels. So, issue the following command to enable the GUI on system start.

# ln -sf /lib/systemd/system/runlevel5.target /etc/systemd/system/default.target

Step 3: Reboot the machine to start the server in the graphical mode.

# reboot

License Agreement:

 

Accept the license by clicking on the “LICENSE INFORMATION“.

 

Install Gnome GUI on CentOS 7 - Licensing Page
Install Gnome GUI on CentOS 7 – Licensing Page

 

Tick mark the “I accept the license agreement” and click on “Done“.

 

 

Install Gnome GUI on CentOS 7 - License Agreement
Install Gnome GUI on CentOS 7 – License Agreement

 

Click on “FINISH CONFIGURATION” to complete the setup.

 

Install Gnome GUI on CentOS 7 - License Accepted
Install Gnome GUI on CentOS 7 – License Accepted

 

You may need to do some post configuration tasks, like creating first user (local account), language, etc.

 

Then finally you will get the desktop.

 

Install Gnome GUI on CentOS 7 - GUI Desktop
Install Gnome GUI on CentOS 7 – GUI Desktop

 

That’s All. You have successfully installed GUI on CentOS 7 / RHEL 7.

在CENTOS7安装RDP,远程控制

xrdp is an Open Source Remote desktop Protocol server, which allows you to RDP to your Linux server from Windows machine; it is capable of accepting connections from rdesktop, freerdp, and remote desktop clients.

This post will help you to setup xrdp server on CentOS 7 / RHEL 7.

Prerequisites

1. First, install Gnome GUI on CentOS 7 / RHEL 7

2. xrdp is available in EPEL repository, so Install and configure EPEL repository.

rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

Install xrdp on CentOS 7

Use YUM command to install xrdp package on CentOS 7 / RHEL 7.

yum -y install xrdp tigervnc-server

Output:

 

Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: centos.excellmedia.net
 * epel: del-mirrors.extreme-ix.org
 * extras: centos.excellmedia.net
 * updates: centos.excellmedia.net
Resolving Dependencies
--> Running transaction check
---> Package tigervnc-server.x86_64 0:1.8.0-2.el7_4 will be installed
---> Package xrdp.x86_64 1:0.9.5-1.el7 will be installed
--> Processing Dependency: xorgxrdp for package: 1:xrdp-0.9.5-1.el7.x86_64
--> Running transaction check
---> Package xorgxrdp.x86_64 0:0.2.5-3.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=================================================================================================
 Package                    Arch              Version                   Repository          Size
=================================================================================================
Installing:
 tigervnc-server            x86_64            1.8.0-2.el7_4             updates            213 k
 xrdp                       x86_64            1:0.9.5-1.el7             epel               413 k
Installing for dependencies:
 xorgxrdp                   x86_64            0.2.5-3.el7               epel                61 k

Transaction Summary
=================================================================================================
Install  2 Packages (+1 Dependent package)

Total download size: 688 k
Installed size: 2.7 M
Downloading packages:
warning: /var/cache/yum/x86_64/7/epel/packages/xrdp-0.9.5-1.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 352c64e5: NOKEY
Public key for xrdp-0.9.5-1.el7.x86_64.rpm is not installed
(1/3): xrdp-0.9.5-1.el7.x86_64.rpm                                        | 413 kB  00:00:01
(2/3): tigervnc-server-1.8.0-2.el7_4.x86_64.rpm                           | 213 kB  00:00:01
(3/3): xorgxrdp-0.2.5-3.el7.x86_64.rpm                                    |  61 kB  00:00:01
-------------------------------------------------------------------------------------------------
Total                                                            409 kB/s | 688 kB  00:00:01
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
Importing GPG key 0x352C64E5:
 Userid     : "Fedora EPEL (7) <epel@fedoraproject.org>"
 Fingerprint: 91e9 7d7c 4a5e 96f1 7f3e 888f 6a2f aea2 352c 64e5
 Package    : epel-release-7-11.noarch (installed)
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Warning: RPMDB altered outside of yum.
  Installing : xorgxrdp-0.2.5-3.el7.x86_64                                                   1/3
  Installing : 1:xrdp-0.9.5-1.el7.x86_64                                                     2/3
  Installing : tigervnc-server-1.8.0-2.el7_4.x86_64                                          3/3
  Verifying  : xorgxrdp-0.2.5-3.el7.x86_64                                                   1/3
  Verifying  : tigervnc-server-1.8.0-2.el7_4.x86_64                                          2/3
  Verifying  : 1:xrdp-0.9.5-1.el7.x86_64                                                     3/3

Installed:
  tigervnc-server.x86_64 0:1.8.0-2.el7_4                xrdp.x86_64 1:0.9.5-1.el7

Dependency Installed:
  xorgxrdp.x86_64 0:0.2.5-3.el7

Complete!
</epel@fedoraproject.org>

Once xrdp is installed, start the xrdp service using the following command.

systemctl start xrdp

xrdp should now be listening on 3389. You can confirm this by using netstat command.

netstat -antup | grep xrdp

Output:

tcp        0      0 0.0.0.0:3389            0.0.0.0:*               LISTEN      1508/xrdp
tcp        0      0 127.0.0.1:3350          0.0.0.0:*               LISTEN      1507/xrdp-sesman

READ: netstat command not found on CentOS 7 / RHEL 7 – Quick Fix

By default, xrdp service won’t start automatically after a system reboot. Run the following command in the terminal to enable the service at system startup.

 

systemctl enable xrdp

Firewall

Configure the firewall to allow RDP connection from external machines. The following command will add the exception for RDP port (3389).

firewall-cmd --permanent --add-port=3389/tcp
firewall-cmd --reload

SELinux

Configure SELinux

 

chcon --type=bin_t /usr/sbin/xrdp
chcon --type=bin_t /usr/sbin/xrdp-sesman

Test xrdp Remote Connectivity

Now take RDP from any windows machine using Remote Desktop Connection. Enter the ip address of Linux server in the computer field and then click on connect.

 

Install xrdp on CentOS 7 - Enter IP Address in Remote Desktop Connecton Window
Install xrdp on CentOS 7 – Enter IP Address in Remote Desktop Connection Window

 

You may need to ignore the warning of RDP certificate name mismatch.

 

 

Install xrdp on CentOS 7 - Accept the Certificate
Install xrdp on CentOS 7 – Accept the Certificate

 

You would be asked to enter the username and password. You can either use root or any user that you have it on the system. Make sure you use module “Xvnc“.

 

Install xrdp on CentOS 7 - xrdp Login Page
Install xrdp on CentOS 7 – xrdp Login Page

 

 

If you click ok, you will see the processing. In less than a half minute, you will get a desktop.

 

 

Install xrdp on CentOS 7 - xrdp CentOS Desktop
Install xrdp on CentOS 7 – xrdp CentOS Desktop

 

That’s All. You have successfully configured xRDP on CentOS 7 / RHEL 7.

一键安装windows

安装所需软件

#Debian/Ubuntu:
apt-get install -y xz-utils openssl gawk file

#RedHat/CentOS:
yum install -y xz openssl gawk file

出现了错误,请运行

#Debian/Ubuntu:
apt-get update

#RedHat/CentOS:
yum update

一键下载及使用

wget --no-check-certificate -qO InstallNET.sh 'https://moeclub.org/attachment/LinuxShell/InstallNET.sh' && chmod a+x InstallNET.sh

#备用地址
wget --no-check-certificate -qO InstallNET.sh 'https://www.fengweishang.com/document/scriptbackup/InstallNET.sh' && chmod a+x InstallNET.sh

安装windows:

bash InstallNET.sh -dd 'http://arv.asuhu.com/dd/newS2008R2DATA.vhd.gz'

ShadowsocksR MudbJSON模式多用户一键脚本 支持流量限制等

系统要求

CentOS 6+ / Debian 6+ / Ubuntu 14.04 +

推荐 Debian 8 x64,这个是我一直使用的系统,我的脚本在这个系统上面出错率最低。并且最容易安装锐速(锐速不支持OpenVZ)

CentOS 7 自带防火墙问题(firewalld)自行解决,其他版本没有做测试。

脚本版本

Ver: 1.0.26

本脚本与另一个SSR脚本 『原创』CentOS/Debian/Ubuntu ShadowsocksR 单/多端口 一键管理脚本 的区别是什么?

ssrmu.sh 脚本是单服务器多用户脚本,使用的是 SSR服务端的MudbJSON模式,可以给每个用户(端口)设置不同的加密方式/协议/混淆/限制速度/设备数限制/可用总流量等功能。即实现单服务器多用户流量管理等功能。

而 ssr.sh 则是单服务器单用户脚本,使用的是 SSR服务端的单用户配置方式,即使实现了多端口,但是还算不算多用户,不支持每个用户(端口)不同的加密方式/协议/混淆等,并且无法管理流量使用。

如何选择这两个脚本?

根据你的需求选择,比如你仅仅是 一个或两个人使用,并且不需要流量管理功能,那么选择 ssr.sh 好了。而如果很多人使用,并且都需要限制流量来管理,那你适合使用 ssrmu.sh ,所以自己看着选,多试试(两个脚本不能共存)

脚本特点:

所有步骤都可以通过 Shell 脚本中文交互 操作。

  1. 支持 限制 用户速度
  2. 支持 限制 用户设备数
  3. 支持 限制 用户总流量
  4. 支持 定时 流量清零
  5. 支持 显示 当前连接IP
  6. 支持 显示 SS/SSR连接+二维码
  7. 支持 自定义账号IP或域名
  8. 支持 监控SSR服务端运行状态
  9. 支持 一键安装 BBR
  10. 支持 一键安装 锐速
  11. 支持 一键安装 LotServer
  12. 支持 一键封禁 垃圾邮件(SMAP)/BT/PT

安装步骤

简单的来说,如果你什么都不懂,那么你直接一路回车就可以了!

本脚本需要Linux root账户权限才能正常安装运行,所以如果不是 root账号,请先切换为root,如果是 root账号,那么请跳过!

sudo su

输入上面代码回车后会提示你输入当前用户的密码,输入并回车后,没有报错就继续下面的步骤安装ShadowsocksR。


注意:如果你安装的有我的另一个 ssr.sh 脚本,请先卸载ShadowsocksR服务端,再安装这个脚本(不能共存)!

wget -N --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/ssrmu.sh && chmod +x ssrmu.sh && bash ssrmu.sh

下载运行后会提示你输入数字来选择要做什么。

输入 1 ,就会开始安装ShadowsocksR服务端,并且会提示你输入Shadowsocks的 端口/密码/加密方式/ 协议/混淆(混淆和协议是通过输入数字选择的) 等参数来添加第一个用户。

注意:用户名不支持中文,如果输入中文会一直保存下去!

如果安装过程中报错,请看 常见问题解决方法

点击展开 查看更多

使用说明

运行脚本,

bash ssrmu.sh

# 还有一个 运行参数,是用于所有用户流量清零的
bash ssrmu.sh clearall
# 不过不需要管这个,可以通过脚本自动化的设置 crontab 定时运行脚本

输入对应的数字来执行相应的命令。

  ShadowsocksR MuJSON一键管理脚本 [vX.X.X]
  ---- Toyo | doub.io/ss-jc60 ----

  1. 安装 ShadowsocksR
  2. 更新 ShadowsocksR
  3. 卸载 ShadowsocksR
  4. 安装 libsodium(chacha20)
————————————
  5. 查看 账号信息
  6. 显示 连接信息
  7. 设置 用户配置
  8. 手动 修改配置
  9. 配置 流量清零
————————————
 10. 启动 ShadowsocksR
 11. 停止 ShadowsocksR
 12. 重启 ShadowsocksR
 13. 查看 ShadowsocksR 日志
————————————
 14. 其他功能
 15. 升级脚本

 当前状态: 已安装 并 已启动

请输入数字 [1-15]:

注意:添加/删除/修改 用户配置后,无需重启ShadowsocksR服务端,ShadowsocksR服务端会定时读取数据库文件内的信息,不过修改 用户配置后,可能要等个十几秒才能应用最新的配置(因为ShadowsocksR不是实时读取数据库的,所以有间隔时间)。

文件位置

安装目录:/usr/local/shadowsocksr

日志位置:/usr/local/shadowsocksr/ssserver.log

配置文件:/usr/local/shadowsocksr/user-config.json

数据文件:/usr/local/shadowsocksr/mudb.json

注意:如果要转移用户数据,只需要转移 mudb.json 文件或其内容即可。

注意:ShadowsocksR服务端不会实时的把流量数据写入 数据库文件,所以脚本读取流量信息也不是实时的!

其他说明

ShadowsocksR 安装后,自动设置为 系统服务,所以支持使用服务来启动/停止等操作,同时支持开机启动。

  1. 启动 ShadowsocksR:/etc/init.d/ssrmu start
  2. 停止 ShadowsocksR:/etc/init.d/ssrmu stop
  3. 重启 ShadowsocksR:/etc/init.d/ssrmu restart
  4. 查看 ShadowsocksR状态:/etc/init.d/ssrmu status

ShadowsocksR 默认支持UDP转发,服务端无需任何设置。

本脚本已经集成了 安装/卸载 锐速(ServerSpeeder)/Lotserver,但是是否支持请查看 Linux支持内核列表 。(锐速、LotServer不支持OpenVZ)


注意:本脚本中的 显示链接信息中的 获取IP归属地功能使用的是 IPIP.NET 的免费API接口,因为限速所以每秒只能检测一次,同时 IPIP.NET 的免费API接口并不会保证稳定性,可能什么时候就突然暂时失效了,这是本人不可控的,有条件可以自建API接口。

ShadowsocksR目前支持的协议和混淆:

协议(Protocol):origin,auth_sha1_v4,auth_aes128_md5,auth_aes128_sha1,auth_chain_a,auth_chain_b

混淆(Obfs):plain,http_simple,http_post,random_head,tls1.2_ticket_auth,tls1.2_ticket_fastauth(这个是客户端用的,而服务端需要选择tls1.2_ticket_auth)

origin 和 plain 是原版,加粗的是推荐使用的。

如果你想要使用 tls1.2_ticket_fastauth 混淆插件,那么服务端选择 tls1.2_ticket_auth,客户端选择 tls1.2_ticket_fastauth 即可。

如果服务端 设置混淆参数为:tls1.2_ticket_auth_compatible (兼容原版)

那么客户端 可使用的混淆为:plain / tls1.2_ticket_auth / tls1.2_ticket_fastauth

tls1.2_ticket_auth 与 tls1.2_ticket_fastauth 的区别为,后者不会等待服务器回应,所以不会增加延迟。适合于,因为混淆插件增加延迟的原因不得不选择原版混淆 plain,但是又因为QOS等因素而处于延迟与干扰/限速等之间抉择的时候,可以选择 tls1.2_ticket_fastauth 客户端混淆插件!

如何转移用户数据信息?

点击展开 查看更多

使用阿里云/腾讯云等存着安全组或规则组一类外部防火墙的请注意

点击展开 查看更多

ShadowsocksR 端口限速中 单线程限速 和 端口总限速 的区别

注意:如果要使用脚本中的这个功能,需要重新下载脚本,并重装安装 2月15日 以后的ShadowsocksR服务端才行。

请查看这个文章:ShadowsocksR服务端 限制设备连接数 和 限制端口速度 的方法

解决 可使用原版协议,但无法使用ShadowsocksR协议 的问题

点击展开 查看更多

提示 Media change: please insert the disc labeled‘Debian GNU/Linux 7.0.0 Wheezy — Official amd64 CD 等信息是 apt源 的问题,更换 apt源

点击展开 查看解决办法

ShadowsocksR启动失败,日志提示:Exception: libsodium not found 的错误

这是你使用了 chacha20 系列加密方式,但是却没有安装 libsodium支持库,导致ShadowsocksR无法启动,运行脚本选择选项 4 安装 libsodium支持库即可,如果安装失败,请选择其他的加密方式,对速度影响不大。

提示wget: unknown host “softs.wtf” 之类的错误

这是无法解析我的域名,多半是DNS的问题,请更换DNS为谷歌DNS。

点击展开 查看更多

 

提示 wget: command not found 的错误

这是你的系统精简的太干净了,wget都没有安装,所以需要安装wget。

点击展开 查看更多

 

升级脚本

升级脚本只需要重新下载脚本文件就可以了,会自动覆盖原文件。

定时重启

一些人可能需要定时重启ShadowsocksR服务端来保证稳定性等,所以这里用 crontab 定时。

点击展开 查看更多

让AMH 的php能在web访问下执行shell

1。安装AMChroot模块,并设置虚拟主机运行为兼容模式。

2。 vi /etc/sudoers

为账号www添加免密码的sudo权限。

把exec_shell改成www

3。一般命令可以执行了,如果需要权限的命令,就加sudo。

切换用户出现:

[root@localhost ~]# su – nagios
This account is currently not available.

运用shell修改用户:

命令:usermod -s /bin/bash username

如果碰到sudo: /etc/sudoers.d is world writable的情况:

执行以下命令

pkexec chmod 555 /etc/sudoers 
pkexec chmod 555 /etc/sudoers.d/README