bower

bower与npm类似都是包管理器,不过后者更适合服务器端项目。

使用npm下载安装

npm install -g bower

使用bower进行安装RequireJS:

bower install requirejs --save

我们可以配置自己的依赖文件,只要创建bower.json执行bower install即可自动下载安装依赖,我们也可以使用bower init为我们生成一个bower.json,我们只需简单配置即可,结果如下。

.
├── bower.json
└── bower_components
    └── requirejs
        ├── README.md
        ├── bower.json
        └── require.js

WebRTC简单总结

Web实时通信技术(Web Real-Time Communication,WebRTC)开创性使得浏览器与其他浏览器互动。实现了浏览器中的实时通信功能。

建立WebRTC会话

建立WebRTC会话需要四个主要步骤:

  • 获取本地媒体,使用getUserMedia函数。

  • 在浏览器和对等端之间建立连接,RTCPeerConnection是WebRTC的核心。需要输入包含ICE(Interactive Connectivity Establishment,交互式连接建立技术)打洞通过各种NAT(Network Address Translation,网络地址转换)设备和防火墙时所使用的信息。

  • 将媒体和数据通道联至该连接。建立连接后,可将任意数量本地媒体流关联到对等连接,通过连接发送到远端浏览器,需要注意每次更改媒体时都需要协商。
  • 交换会话描述,从本地或远端发出添加或删除请求时,可请求浏览器生成相应的RTCSessionDescription对象。

  • 1.A请求

  • 2.A返回

  • 3.B请求

  • 4.B返回

  • 5.A决定与B通信,发送会话描述对象(offer,提议)至服务器。

  • 6.服务器将offer发给B

  • 7.B发送会话描述对象(answer,应答)至服务器。

  • 8.A收到服务器传发的answer。

  • 9.A与B打洞

  • 10.协商

  • 11.交换

本地媒体

MediaStreamTrack是WEBRTC中基本媒体单元,MediaStream是MediaStreamTrack对象的集合。

获取本地媒体,可使用applyConstraints设置约束。

 function getMedia() {
  getUserMedia({"audio":true, "video":true},
               gotUserMedia, didntGetUserMedia);
}

function gotUserMedia(stream) {
  myVideoStream = stream;

  // display my local video to me
  attachMediaStream(myVideo, myVideoStream);
}

function didntGetUserMedia() {
  console.log("couldn't get video");
}

信令

在通信中,信令主要作用体现四个方面:

  • 协商媒体功能和设置。
  • 标识和验证会话参与者的身份。
  • 控制媒体会话、指示进度、更改会话和终止会话。
  • 当会话双方同时尝试建立或更改会话时,实施双占分解。

信令方案:

  • WebSocket代理
  • XML http请求
  • SIP
  • Jingle
  • 数据通道

打洞

可以使用turnserver搭建TURN和STUN服务。

  • STUN(Session Traversal Utilities for NAT)

  • TURN(Traversal Using Relay around NAT)

总结

WebRTC易于使用、只需几个步骤即可建立媒体会话,最近项目比较忙,简单总结,与实践结合可以提高对知识的认识。

快节奏、慢生活

​ 这是关于《快节奏,慢生活》阅读笔记,它主要讲述了通过观察电子产品对生活带来的影响,为什么会这样。本书并不给出实际建议,而是希望通过练习、观察、总结、分享讨论,读者自已来发现适合自己的行为准则,改变自己的生活。

一个女子由于走路专注摆弄手机而掉入广场的喷泉的事件比比皆是,这样的事能带来什么反思?电子设备对生活有什么影响?结论是电子设备有时会太过吸引人,但是电子设备的功大于过,我们又需要依赖它。然而我们对电子设备投入越多精力我们就会越是心不在焉,更加容易掉入喷泉里。我们正处于科技洪流,摆在我们面前的选择越多,我们就越难进行选择。

如果我们集中注意力,处于放松姿势并达到情感平衡时,我们在网络的活动效率就会提高,也会以更健康的方式来工作。这个不只适用于网络活动,同时适用于其他社会活动。然而改变的关键就是注意力,我们通过练习提高注意力。

我们可以把工作(上网)当成“手艺”,可以通过练习进行强化和改善。所以多数是以练习的方式让自己找出适合自己的答案。当你被告知一件事时是没有效果的,只要我们自己发现自己的习惯我们就更容易改变

一个熟悉的故事

作者早晨来到咖啡馆准备大干一场,有个好的计划,身体、思想都处理良好状态,打开工作后,同时顺手开始收邮件(担心有遗漏邮件),收完邮件视线停留在上周未完成的任务并读到一条令人不安的消息(一直拖延的任务),心里开始感觉到焦虑,随手打开网页(逃避),查看有没有什么有趣的新闻,之后猛发现自己的拖延行为并责怪自己分散注意力,开始认真阅读并回邮件,读邮件时听到收到邮件声音,立刻分散注意力(无意识)去看邮件标题和作者,然后继续回来回复邮件,接着手机又响了,妻子打来的,接通发现是无关紧要的小事,作者变得有些不耐烦,更加焦虑起来,呼吸急促同时坐姿也变得不端正(有些驼背)。

我们无时无刻的在做选择,下步要关注什么,关注多久,其中有些是有意识控制的,此些是无意识的。在一堆无 意识的情绪下,作者进行了多次切换,无实质损害,但它们也毫无工作时应有的效率及技巧,而且切换是有时间成本的,最后不端正的坐姿和急促的呼吸能够表明当时所承受的压力。

注意力、情感和身体

注意力

什么是注意力?这是一种以清晰且生动的形式,在多个看起来同样重要的物体或思想中选择出一个并专注它的行为。它的对立面就是干扰,一种“迷惑、迷茫、慌张的状态”。

注意力模式

人类的注意力是种调焦机制,是最原始的技能用来追踪猎物与关注周围环境。我们面临的挑战就是如何更有技巧地同时使用这两种模式:

  • 聚焦式注意力(任务专注力)
    • 就像黑暗房间中探索的插电筒光,所照之处清晰。如深度阅读、集中精力听音乐等。
  • 开放式注意力(自我观察力)
    • 这时不仅可以专注单一物体,而且能够接收到周边环境所发生的事,相当于手电筒发出的是散光,可见范围很大,清晰度会下降。

注意力的转换和选择

知道了注意力的两种模式后,我们面临的挑战是:需要牢记当下意图和目标,这样精力不会无目的的游移,同样意味着我们有时需要有技巧地面对干扰。简要的表述就是:我们需要控制自己抗干扰

控制自己

要想控制自己我们需要先了解人类的控制系统。就像计算机一样,人也有自己的控制系统。

  • 从上至下控制系统
    • 由你意识控制的,它能让你自由选择去关注什么。比如:专注左脚的感受,调动你的局部知觉,你能做到的。
  • 从下至上控制系统
    • 是人类为了生存早期进化完全自动化的控制机制,它能扫描周边环境预防潜在威胁,我们不能停止这种警戒机制。比如:人们经常能被路上跑车的轰鸣声吸引,人的注意力会自然的转移到汽车上。
抗干扰

干扰无处不在,我们可以尽量关闭不必要的干扰,但是不能做到排除所有干扰。我们可以在它们产生时注意到它们,并做出有技巧性的决定,是忽略还是反应。换句话说,我们可以通过强化自我意识,增加选择的可能性,并避免无意识的反应。说了这么多抗干扰,那干扰有什么那?

  • 外部干扰
    • 声音、气味、行动及感知周围物质世界。
  • 内部干扰
    • 由思想和身体中产生,比如:由饥饿感到胃痛。

一心多用— 一种注意力训练

注意力是一心多用的重点。人也像计算机一样,同一时间只关注一件事,来回切换,只不过是速度太快,当许多潜在物体都可以被我们关注时,我们就有了选择的能力。

一心多用的缺点是什么?严格说它是没有效率的,连续转换聚焦式注意力需要时间,经济学家把转换注意力花费时间叫作”转换成本“,我们转换越频繁我们在转换上花费的时间就越多,相应的我们的任务或活动的时间就会更少。而且任务之间由于切换引起的衔接问题也是一种成本。

那它的优点?一件事快速转换另一件事的开放式注意力也是有价值的,思想神游让我们会富有创作性。

当我们掌握强化任务注意力、自我意识和做出明智使用注意力的能力—恰好能够帮助我们更成功地进行一心多用并决定何时(以及何时不)进行。

情感

现在的生活节奏越来越快,我们的生活更有挑战性的是:长时间低落情绪的存在。

感情是无价之宝,让我们的生活更有意义,由下至上的警戒系统中产生负面情绪,这种是机制是遗传的,不可或缺的一部分,比如:当我们害怕,为了在紧急时做出反应,从而升高血压心率,快速反应后迅速恢复常态,科学家称为体内平衡。研究表明:当战斗或逃跑成为常态时,身体就不会恢复到基础状态,身体在高度紧张状态下,能够引发一系列问题。

对于这种机制,我们可以抑制或反思,暂停足够长的时间来重新评估,并且我们可能不能关闭它,但我们可以在产生情感时锻炼自制力,做出有意识的选择。

身体

当我们投入工作或上网时会忽略由下至上传回的信号,以至于身体经受病痛折磨,反过来强烈的身体感觉又如同负面情绪一样能够劫持我们的注意力。

我们需要关注身体,否则它会拖累我们。可以通过改变姿势和动作,能改善心情提高注意力质量。比如:散步。

同时我们也需要注意呼吸也占据着特殊的位置,呼吸是自动的,很有少人会关注它。当我们压力过支时我们经常快速浅呼吸,是我们战斗或逃跑的特征,这时呼吸就会剥夺身体需要氧气的权力。

强化任务专注力

我们一起了解了注意力、情感和身体对我们生活的影响。当我们更细心、更放松达到感情平衡时,我们的工作效率会更高。通过自我观察并留心自身的举动,我们可以学习怎样变得更细心、放松并保持情感平衡:关注我们的思想和身体变化,关注何时及什么什么分心,为什么压力过多或感到沮丧,并运用观察到的东西来调整我们的行为。我们该如何强化任务专注力?

正念呼吸

把呼吸当作关注对象,关注吸入和呼出的呼吸,当思想神游时,你只需要将你关注重点重新放在呼吸上。拉回即可。这种训练可以强化聚焦、开放和选择。正念呼吸可以在任何时间进行,有的时候可能由于外界环境无法专注,可以试试在心里数自己的呼吸。呼~1,吸~2……

正念自省(冥想检查)

正念自省让你变得更加注意你的注意力、你的情感、你的呼吸和身体。花几分钟时间依次询问这些问题。

  • 你的呼吸质量如何:浅还是深,快还是慢?你在屏住呼吸吗?
  • 你的身体内部和身体本身发生了什么变化?姿势是什么样的?你能否注意到身体紧绷或者疼痛的部位?你有没有觉得身体的哪些部位是麻木的?
  • 你现在心情是怎样的?觉得开心、沮丧、激动、还是无聊、焦虑?
  • 你的注意力是怎样的?高度集中,还是四散各处,还是处于中间?

这是一门手艺

我们可以把有效的工作(上网)看作为一种”手艺“,一种高技巧性活动集合,就像其他手艺一样,比如:踢球、游泳。这些手艺是有共同点:注意力的价值、平衡的情感状态和一个放松合拍的身体。这也突出了手艺是可以通过练习和训练进行强化、改善的。那么让们一起掌握这些练习吧?

Tmux

tmux is a software application that can be used to multiplex several virtual consoles, allowing a user to access multiple separate terminal sessions inside a single terminal window or remote terminal session.

安装

各个发行版的包管理工具都能很方便的安装,mac osx 下使用Homebrew进行安装:

brew update
brew install tmux

tmux 与 screen 操作对比

显示session列表
– tmux ls
– screen -ls

session创建
– tmux new -s session-name
– screen -S session-name

session取回
– tmux attach
– screen -r

session附加
– tmux attach -t session-name
– screen -r session-name

tmux 常用功能

tmux默认prefix快捷键是C-b(Ctrl + b) ,习惯使用Screen快捷键可以通过修改~/.tmux.conf调整为C-a

# Set the prefix to ^A.
unbind C-b
set -g prefix ^A
bind a send-prefix

下面列出常用功能:
* C-b c 创建一个新窗口
* C-b d 卸载当前窗口
* C-b n 切换到下一个窗口
* C-b p 切换到上一个窗口
* C-b & 删除当前窗口
* C-b , 修改当前窗口名称
* C-b w 列出所有session窗口,可通过标号进行选择
* C-b q 列出所有区块标号,可通过标号进行选择
* C-b % 垂直平分出一个新区块
* C-b o 切换到下一个区块
* C-b { 区块左移
* C-b } 区块右移
* C-b ? 帮助
* C-b :split-window -h 水平分出一个新区块
* C-b :split-window -v 垂直分出一个新区块

MyBookLive重装

重装

家里有一台MyBookLive作为微型NAS,很老旧了,但是一直很好用,与家里的Apple TV3配合很好,想看的东西拖入transmission,它会自动下载,下完后使用ATV3进行观看,1080p基本无卡顿,上面也装了几个小服务在跑,进行必需备份与娱乐完全够用,就没有再折腾,前几天突然心血来潮给改了密码,之后就悲剧了,密码忘记了,虽然功能正常使用,但是对这台设备没有绝对控制权对我来说还是很不爽的,所以选择重装,还好之前有留后手:)

之前把全新镜像rootfs.img放在/DataVolume/shares/Public/内,并把系统resetButtonAction.sh替换掉,这样在系统出现问题就可以通过MyBookLive上面的reset按钮进行系统恢复,并且数据是不会丢失的,不过建议事先备份,总有不靠谱的时候。

#!/bin/bash

PATH=/sbin:/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

echo red > /sys/class/leds/a3g_led/color
echo yes > /sys/class/leds/a3g_led/blink

echo

#sets $image_img
image_img="/DataVolume/shares/Public/rootfs.img"
echo

# Sort out what MD device is what
currentRootDevice=`cat /proc/cmdline | awk '/root/ { print $1 }' | cut -d= -f2`
if [ "${currentRootDevice}" = "/dev/md0" ]; then
    upgradeRootDevice="/dev/md1"
elif [ "${currentRootDevice}" = "/dev/md1" ]; then
    upgradeRootDevice="/dev/md0"
else
    echo "Unknown rootfs boot device: '${currentRootDevice}', exiting."
    exit 1
fi

echo "currentRootDevice = ${currentRootDevice}"
echo "upgradeRootDevice = ${upgradeRootDevice}"
echo

# If the upgrade MD device is used, shut it down
if [ -e $upgradeRootDevice ]; then
    echo "stopping upgrade md device ${upgradeRootDevice}"
    echo
    mdadm --stop $upgradeRootDevice
    mdadm --wait $upgradeRootDevice
    sleep 1
fi

echo "Ensure both partitions are members of the original MD device"
# "--remove" only remove failed disks and "--add" them causes resyncing
mdadm ${currentRootDevice} --remove /dev/sda1 #> /dev/null 2>&1
mdadm ${currentRootDevice} --add /dev/sda1    #> /dev/null 2>&1
mdadm --wait ${currentRootDevice}
mdadm ${currentRootDevice} --remove /dev/sda2 #> /dev/null 2>&1
mdadm ${currentRootDevice} --add /dev/sda2    #> /dev/null 2>&1
mdadm --wait ${currentRootDevice}
sleep 1

echo
echo "Setting up the upgraded raid unit"
sync
mdadm --wait ${currentRootDevice}
mdadm ${currentRootDevice} -f /dev/sda1 -r /dev/sda1 2> /dev/null > /dev/null
mdadm --wait ${currentRootDevice}
sleep 1
mdadm --zero-superblock --force --verbose /dev/sda1
mdadm --create ${upgradeRootDevice} --verbose --metadata=0.9 --raid-devices=2 --level=raid1 --run /dev/sda1 missing
mdadm --wait ${upgradeRootDevice}
sleep 1
sync
mkfs.ext3 -c -b 4096 ${upgradeRootDevice}
sync
echo

# installing new image on update device
# img file was searched for by ./findImage.sh
echo "Copy image to upgrade device ${upgradeRootDevice}"
dd if=${image_img} of=${upgradeRootDevice}
echo

# new OS was accepted
mkdir -p /mnt/rootfs
mount ${upgradeRootDevice} /mnt/rootfs

#needed
touch /mnt/rootfs/etc/.updateInProgress
chmod 777 /mnt/rootfs/etc/.updateInProgress

#enable ssh
echo "enabled" > /mnt/rootfs/etc/nas/service_startup/ssh

# copy uboot script too boot directory
if [ ${upgradeRootDevice} == "/dev/md0" ]; then
    cp /mnt/rootfs/usr/local/share/bootmd0.scr /mnt/rootfs/boot/boot.scr
else
    cp /mnt/rootfs/usr/local/share/bootmd1.scr /mnt/rootfs/boot/boot.scr
fi

# some safety since it is a critical step here
sync
sleep 2
umount /mnt/rootfs
sleep 2
sync
echo

# ensures reboot
echo no     > /sys/class/leds/a3g_led/blink
echo yellow > /sys/class/leds/a3g_led/color
echo "all done, now rebooting"
shutdown -r 0

install optware

使用ssh连接到MyBookLive执行下面命令进行optware安装。

wget http://mybookworld.wikidot.com/local--files/optware/setup-mybooklive.sh
sh setup-mybooklive.sh

创建ipkg连接

echo "export PATH=$PATH:/opt/bin:/opt/sbin" >> /root/.bashrc
echo "export PATH=$PATH:/opt/bin:/opt/sbin" >> /etc/profile

重新连接后输入命令进行更新,optware就安好了。

ipkg update

安装 transmission2.84

之前一直使用transmission 进行离线下载,所以这个是必装的,2.84需要自己编译所以时间会长一些。

#!/bin/bash
#
#Compile and Install transmission bittorrent client on mybooklive
#
#Author: Proglin 2015-09-10
#
# Update: 2017-06-14 Update main code with suggestions from HTaborda and olimatis.
# Update: 2016-10-06 by olimatis: New source for Transmission
# Update: 2016-04-24 by HTaborda: Introduced --no-check-certificate to the Transmission source download; server certificate outdated
# Update: 2016-02-26 LibEvent Extract Folder name changed + Compile Changed
# Update: 2016-02-22 LibEvent URL changed
#
# Note:
#  I strong recommend you to download an update firmware
#  Save it in public folder
#  If anything goes wrong you can update your firmware to clean the mess using:
#    /usr/local/sbin/updateFirmwareFromFile.sh /DataVolume/shares/Public/apnc-024310-048-20150507.deb
#
# References:
#https://trac.transmissionbt.com/wiki/Building#DebianSqueeze
#https://trac.transmissionbt.com/wiki/Scripts/initd
#http://falkhusemann.de/blog/2012/05/compiling-transmission-bittorrent-for-debiand/
#http://community.wd.com/t5/My-Book-Live/GUIDE-How-to-unbrick-a-totally-dead-MBL/td-p/435724
#http://support.wd.com/product/download.asp?groupid=902&sid=132&lang=en
start=$SECONDS

# CONFIGURATION TRANSMISSION VERSION
TRANSMISSIONSOURCE='https://github.com/transmission/transmission-releases/raw/master/transmission-2.84.tar.xz'

# EXTRA CONFIGURATIONS
#TMPFOLDER='/root/temp'
#LIBEVENTSOURCE='http://sourceforge.net/projects/levent/files/libevent/libevent-2.0/libevent-2.0.18-stable.tar.gz'
LIBEVENTSOURCE='https://github.com/libevent/libevent/archive/release-2.0.18-stable.tar.gz'
LIBEVENTEXTRACTNAME='libevent-release-2.0.18-stable.tar.gz'

#Change TMP Folder to have more space!
TMPFOLDER='/shares/Public/tmpCompile'
TMP=$TMPFOLDER
TEMP=$TMPFOLDER
TMPDIR=$TMPFOLDER
export TMPDIR TMP TEMP

clear
echo "Welcome! Compile and Install Transmission 2.84"
echo "Created by Proglin v2015-09-10"
echo "      Last Update: v2017-06-14"
echo "ALWAYS back up your data before proceeding."
echo "This script was only tested with MyBookLive firmware 02.43.10-048"
printf "Your firmware version is: ";tail -1 /var/log/version.log
echo ""
echo "NOTE from Author: I have not MyBookLive since 2016. Changes after 2016 are based"
echo "                  on user forum comments."
echo ""
echo "We are going to change some configs to install Tranmission"
read -p "This process takes around 30 minutes. Are you sure? (Y/N)" -n 1 -r
echo    # (optional) move to a new line
if [[ $REPLY =~ ^[Nn]$ ]]
then
    echo "OK. Exiting."
    exit
fi

mkdir -p $TMPFOLDER
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
fi

rm -f /var/lib/dpkg/info/wd-nas.*
cp /etc/apt/sources.list $TMPFOLDER/sources.list.bak
echo ""
printf "1/22 Configuring repositories... (part 1/3)"
APTSOURCESOLD="#Modified to install Transmission (old packages)
deb http://archive.debian.org/debian/ squeeze main
deb-src http://archive.debian.org/debian/ squeeze main
#deb http://ftp.br.debian.org/debian/ wheezy main
#deb-src http://ftp.br.debian.org/debian/ wheezy main\n"
printf "$APTSOURCESOLD" > /etc/apt/sources.list

apt-get -qq clean
apt-get -qq update >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

printf "2/22 Installing packages... (part 1/7)"
apt-get -q -y --force-yes --allow-unauthenticated -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" -o Dpkg::Options::="--force-overwrite" install tar >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

printf "3/22 Installing packages... (part 2/7)"
apt-get -q -y --force-yes --allow-unauthenticated -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" -o Dpkg::Options::="--force-overwrite" install ca-certificates >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

printf "4/22 Installing packages... (part 3/7)"
apt-get -q -y --force-yes --allow-unauthenticated -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" -o Dpkg::Options::="--force-overwrite" install intltool >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

printf "5/22 Installing packages... (part 4/7)"
apt-get -q -y --force-yes --allow-unauthenticated -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" -o Dpkg::Options::="--force-overwrite" install build-essential >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

printf "6/22 Installing packages... (part 5/7)"
apt-get -q -y --force-yes --allow-unauthenticated -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" -o Dpkg::Options::="--force-overwrite" install libtool >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

printf "7/22 Configuring repositories... (part 2/3)"
APTSOURCESNEW="#Modified to install Transmission (new packages)
#deb http://archive.debian.org/debian/ squeeze main
#deb-src http://archive.debian.org/debian/ squeeze main
deb http://ftp.br.debian.org/debian/ wheezy main
deb-src http://ftp.br.debian.org/debian/ wheezy main\n"
printf "$APTSOURCESNEW" > /etc/apt/sources.list
apt-get -qq clean
apt-get -qq update 2>/dev/null
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

printf "8/22 Installing packages... (part 6/7)"
export DEBIAN_FRONTEND=noninteractive
apt-get -qq -y --force-yes --allow-unauthenticated -o Dpkg::Options::="--force-confold" -o Dpkg::Options::="--force-overwrite" -o Dpkg::Options::="--force-confdef" install libssl-dev >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

printf "9/22 Configuring repositories... (part 3/3)"
APTSOURCESOLD="#Modified to install Transmission (old packages)
deb http://archive.debian.org/debian/ squeeze main
deb-src http://archive.debian.org/debian/ squeeze main
#deb http://ftp.br.debian.org/debian/ wheezy main
#deb-src http://ftp.br.debian.org/debian/ wheezy main\n"
printf "$APTSOURCESOLD" > /etc/apt/sources.list

apt-get -qq clean
apt-get -qq update >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

printf "10/22 Installing packages... (part 7/7)"
apt-get -q -y --force-yes --allow-unauthenticated -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" -o Dpkg::Options::="--force-overwrite" install libcurl4-openssl-dev >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

printf "11/22 Downloading sources of LIBEVENT..."
#Getting sources of Transmission and LibEvent
#wget -q $LIBEVENTSOURCE -O $TMPFOLDER/${LIBEVENTSOURCE##*/} >/dev/null 2>&1
wget -q $LIBEVENTSOURCE -O $TMPFOLDER/$LIBEVENTEXTRACTNAME >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
fi
#extract
#tar xf $TMPFOLDER/${LIBEVENTSOURCE##*/} -C $TMPFOLDER >/dev/null 2>&1
tar xf $TMPFOLDER/$LIBEVENTEXTRACTNAME -C $TMPFOLDER >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

printf "12/22 Downloading sources of TRANSMISSION"
#Getting sources of Transmission and LibEvent
#wget -q $TRANSMISSIONSOURCE -O $TMPFOLDER/${TRANSMISSIONSOURCE##*/} >/dev/null 2>&1
wget --no-check-certificate -q $TRANSMISSIONSOURCE -O $TMPFOLDER/${TRANSMISSIONSOURCE##*/} >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
fi
#extract
tar xf $TMPFOLDER/${TRANSMISSIONSOURCE##*/} -C $TMPFOLDER >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

#clean cache
apt-get clean

#Getfilenames of directories
#AFTER_SLASH=${LIBEVENTSOURCE##*/}
#file="${AFTER_SLASH%%\?*}"
file=${LIBEVENTEXTRACTNAME}
DIRLIBEVENTSOURCE=${file%.tar.xz}
DIRLIBEVENTSOURCE=${DIRLIBEVENTSOURCE%.tar.gz}

#Configure LIBEVENT
cd $TMPFOLDER/$DIRLIBEVENTSOURCE
printf "13/22 Configuring LIBEVENT to compile..."
./autogen.sh >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
fi
./configure --prefix=/usr >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

#Compile LIBEVENT
printf "14/22 Compiling LIBEVENT..."
make >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

#Install LIBEVENT
printf "15/22 Installing LIBEVENT..."
make install >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

#Configure TRANSMISSION
AFTER_SLASH=${TRANSMISSIONSOURCE##*/}
file="${AFTER_SLASH%%\?*}"
DIRTRANSMISSION=${file%.tar.xz}
DIRTRANSMISSION=${DIRTRANSMISSION%.tar.gz}

cd $TMPFOLDER/$DIRTRANSMISSION
printf "16/22 Configuring TRANSMISSION to compile..."
./configure --prefix=/usr --enable-lightweight --enable-daemon --enable-utp >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

#Compile TRANSMISSION
printf "17/22 Compiling TRANSMISSION..."
make >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi

#Install TRANSMISSION
printf "18/22 Installing TRANSMISSION..."
#mkdir -p /root/.config/transmissiond
make install >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi


#settings.json
read -d '' SETTINGSJSON <<"EOF"
{
    "alt-speed-down": 300, 
    "alt-speed-enabled": true, 
    "alt-speed-time-begin": 420, 
    "alt-speed-time-day": 127, 
    "alt-speed-time-enabled": true, 
    "alt-speed-time-end": 30, 
    "alt-speed-up": 10, 
    "bind-address-ipv4": "0.0.0.0", 
    "bind-address-ipv6": "::", 
    "blocklist-enabled": true, 
    "blocklist-url": "http://list.iblocklist.com/?list=bt_level1&fileformat=p2p&archiveformat=gz", 
    "cache-size-mb": 8, 
    "dht-enabled": true, 
    "download-dir": "/DataVolume/shares/Public/Torrents/Completed", 
    "download-queue-enabled": true, 
    "download-queue-size": 5, 
    "encryption": 2, 
    "idle-seeding-limit": 30, 
    "idle-seeding-limit-enabled": true, 
    "incomplete-dir": "/DataVolume/shares/Public/Torrents/Incomplete", 
    "incomplete-dir-enabled": true, 
    "lazy-bitfield-enabled": true, 
    "lpd-enabled": false, 
    "message-level": 2, 
    "peer-congestion-algorithm": "lp", 
    "peer-id-ttl-hours": 6, 
    "peer-limit-global": 260, 
    "peer-limit-per-torrent": 80, 
    "peer-port": 51003, 
    "peer-port-random-high": 65535, 
    "peer-port-random-low": 49152, 
    "peer-port-random-on-start": false, 
    "peer-socket-tos": "lowcost", 
    "pex-enabled": true, 
    "port-forwarding-enabled": false, 
    "preallocation": 2, 
    "prefetch-enabled": 0, 
    "queue-stalled-enabled": true, 
    "queue-stalled-minutes": 60, 
    "ratio-limit": 0.1000, 
    "ratio-limit-enabled": true, 
    "rename-partial-files": true, 
    "rpc-authentication-required": false, 
    "rpc-bind-address": "0.0.0.0", 
    "rpc-enabled": true, 
    "rpc-password": "{ee82e7a5337f8d06704c133d83fd69da54bdc785ixojPp6Z", 
    "rpc-port": 9091, 
    "rpc-url": "/transmission/", 
    "rpc-username": "transmission", 
    "rpc-whitelist": "127.0.0.1,192.168.*.*", 
    "rpc-whitelist-enabled": true, 
    "scrape-paused-torrents-enabled": true, 
    "script-torrent-done-enabled": false, 
    "script-torrent-done-filename": "/DataVolume/shares/Public/Torrents/Scripts/processaTorrent.sh", 
    "seed-queue-enabled": true, 
    "seed-queue-size": 10, 
    "speed-limit-down": 1100, 
    "speed-limit-down-enabled": true, 
    "speed-limit-up": 85, 
    "speed-limit-up-enabled": true, 
    "start-added-torrents": true, 
    "trash-original-torrent-files": true, 
    "umask": 0, 
    "upload-slots-per-torrent": 8, 
    "utp-enabled": true, 
    "watch-dir": "/DataVolume/shares/Public/Torrents/Monitora", 
    "watch-dir-enabled": false
}

EOF

#INIT.D file
read -d '' INITD <<"EOF"
#! /bin/sh
### BEGIN INIT INFO
# Provides:          transmission-daemon
# Required-Start:    networking
# Required-Stop:     networking
# Default-Start:     2 3 5
# Default-Stop:      0 1 6
# Short-Description: Start the transmission BitTorrent daemon client.
### END INIT INFO

# Original Author: Lennart A. Jaette, based on Rob Howell's script
# Modified by Maarten Van Coile & others (on IRC)

# Do NOT "set -e"

#
# ----- CONFIGURATION -----
#
# For the default location Transmission uses, visit:
# http://trac.transmissionbt.com/wiki/ConfigFiles
# For a guide on how set the preferences, visit:
# http://trac.transmissionbt.com/wiki/EditConfigFiles
# For the available environement variables, visit:
# http://trac.transmissionbt.com/wiki/EnvironmentVariables
#
# The name of the user that should run Transmission.
# It's RECOMENDED to run Transmission in it's own user,
# by default, this is set to 'transmission'.
# For the sake of security you shouldn't set a password
# on this user
USERNAME=root


# ----- *ADVANCED* CONFIGURATION -----
# Only change these options if you know what you are doing!
#
# The folder where Transmission stores the config & web files.
# ONLY change this you have it at a non-default location
#TRANSMISSION_HOME="/var/config/transmission-daemon"
#TRANSMISSION_WEB_HOME="/usr/share/transmission/web"
#
# The arguments passed on to transmission-daemon.
# ONLY change this you need to, otherwise use the
# settings file as per above.
#TRANSMISSION_ARGS=""


# ----- END OF CONFIGURATION -----
#
# PATH should only include /usr/* if it runs after the mountnfs.sh script.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
DESC="bittorrent client"
NAME=transmission-daemon
DAEMON=$(which $NAME)
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
[ -f /etc/default/rcS ] && . /etc/default/rcS

#
# Function that starts the daemon/service
#

do_start()
{
    # Export the configuration/web directory, if set
    if [ -n "$TRANSMISSION_HOME" ]; then
          export TRANSMISSION_HOME
    fi
    if [ -n "$TRANSMISSION_WEB_HOME" ]; then
          export TRANSMISSION_WEB_HOME
    fi

    # Return
    #   0 if daemon has been started
    #   1 if daemon was already running
    #   2 if daemon could not be started
    start-stop-daemon --chuid $USERNAME --start --pidfile $PIDFILE --make-pidfile \
            --exec $DAEMON --background --test -- -f $TRANSMISSION_ARGS > /dev/null \
            || return 1
    start-stop-daemon --chuid $USERNAME --start --pidfile $PIDFILE --make-pidfile \
            --exec $DAEMON --background -- -f $TRANSMISSION_ARGS \
            || return 2
}

#
# Function that stops the daemon/service
#
do_stop()
{
        # Return
        #   0 if daemon has been stopped
        #   1 if daemon was already stopped
        #   2 if daemon could not be stopped
        #   other if a failure occurred
        start-stop-daemon --stop --quiet --retry=TERM/10/KILL/5 --pidfile $PIDFILE --exec $DAEMON 
        RETVAL="$?"
        [ "$RETVAL" = 2 ] && return 2

        # Wait for children to finish too if this is a daemon that forks
        # and if the daemon is only ever run from this initscript.
        # If the above conditions are not satisfied then add some other code
        # that waits for the process to drop all resources that could be
        # needed by services started subsequently.  A last resort is to
        # sleep for some time.

        start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
        [ "$?" = 2 ] && return 2

        # Many daemons don't delete their pidfiles when they exit.
        rm -f $PIDFILE

        return "$RETVAL"
}

case "$1" in
  start)
        echo "Starting $DESC" "$NAME..."
        do_start
        case "$?" in
                0|1) echo "   Starting $DESC $NAME succeeded" ;;
                *)   echo "   Starting $DESC $NAME failed" ;;
        esac
        ;;
  stop)
        echo "Stopping $DESC $NAME..."
        do_stop
        case "$?" in
                0|1) echo "   Stopping $DESC $NAME succeeded" ;;
                *)   echo "   Stopping $DESC $NAME failed" ;;
        esac
        ;;
  restart|force-reload)
        #
        # If the "reload" option is implemented then remove the
        # 'force-reload' alias
        #
        echo "Restarting $DESC $NAME..."
        do_stop
        case "$?" in
          0|1)
                do_start
                case "$?" in
                    0|1) echo "   Restarting $DESC $NAME succeeded" ;;
                    *)   echo "   Restarting $DESC $NAME failed: couldn't start $NAME" ;;
                esac
                ;;
          *)
                echo "   Restarting $DESC $NAME failed: couldn't stop $NAME" ;;
        esac
        ;;
  *)
        echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
        exit 3
        ;;
esac

EOF

#Setting TRANSMISSION to auto startup
printf "19/22 Configuring TRANSMISSION to auto startup"
printf "$INITD" > /etc/init.d/transmission-daemon
chmod +x /etc/init.d/transmission-daemon
chown root:root /etc/init.d/transmission-daemon
#Adding autostart to transmission
update-rc.d transmission-daemon defaults >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi


#Starting TRANSMISSION
printf "20/22 Configuring TRANSMISSION settings.json"
/etc/init.d/transmission-daemon start >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
fi

#Wait transmission to create config files structure
sleep 5

/etc/init.d/transmission-daemon stop >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
fi

#configuring SETTINGS.JSON
printf "$SETTINGSJSON" > /root/.config/transmission-daemon/settings.json
echo " OK!"

printf "21/22 Cleaning temp files"
#Cleaning temp files
cp /etc/apt/sources.list /etc/apt/sources.list.new
cat $TMPFOLDER/sources.list.bak > /etc/apt/sources.list
rm -rf $TMPFOLDER
apt-get clean
echo " OK!"

#Starting TRANSMISSION
printf "22/22 Starting TRANSMISSION"
/etc/init.d/transmission-daemon start >/dev/null 2>&1
if [[ $? > 0 ]]
then
    echo "The command failed, exiting." ; exit
else
    echo " OK!"
fi


end=$SECONDS
echo "Total time: $((end - start)) secs."
echo "Done!"
echo "Cross your fingers and access http://mybooklive:9091/"
echo "TODO: REMEMBER to configure: settings.json" 
echo ""

安装好后修改配置文件。

vim /root/.config/transmission-daemon/settings.json

安装视频服务器

视频服务器使用appletv-mserver版本的,我之前使用的是旧版,这次用新的。

旧版

tar zxvf appletv-mserver-121218.tgz
chmod 755 install.sh
./install.sh
apt-get install screen

编辑/etc/rc.local,添加screen -d -m -S avs /opt/avs/startavs.sh

vim /etc/rc.local
screen -d -m -S avs /opt/avs/startavs.sh

新版

旧版发布的release不是最新的,所以可以使用下面脚本从install packages开始,可以使用svn上最新代码。

#install optware
IPKG=`which ipkg`
if [ -z "$IPKG" ]; then
wget -O - http://mybookworld.wikidot.com/local--files/optware/setup-mybooklive.sh|sh
echo "export PATH=$PATH:/opt/bin:/opt/sbin" >> /root/.bashrc
echo "export PATH=$PATH:/opt/bin:/opt/sbin" >> /etc/profile
fi
export PATH=$PATH:/opt/bin:/opt/sbin
wget -P /etc/init.d http://mybookworld.wikidot.com/local--files/optware/optware.sh
chmod +x /etc/init.d/optware.sh
update-rc.d optware.sh defaults 90 01
mkdir -p /opt/etc/init.d/
# install packages
ipkg update

ipkg install screen
ipkg install svn
ipkg install patch

# configure apache
# ln -s /DataVolume/shares/ /var/www/shares
ln -s /etc/apache2/mods-available/autoindex.conf /etc/apache2/mods-enabled/
ln -s /etc/apache2/mods-available/autoindex.load /etc/apache2/mods-enabled/
ln -s /etc/apache2/mods-available/cgi.load /etc/apache2/mods-enabled/
apache2ctl restart
# install appletv-mserver

cd /root
#svn co http://appletv-mserver.googlecode.com/svn/trunk
wget http://182.16.230.98/appletv-mserver.tgz
tar zxvf appletv-mserver.tgz
cd trunk
sh install.sh

/opt/avs/avs.sh restart

修改我成需要的版本

vim /etc/apache2/sites-available/avs


Listen 8000 <VirtualHost *:8000> ServerAdmin webmaster@localhost DocumentRoot /DataVolume/shares/x/Public/WWW/TR-Downloads <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /DataVolume/shares/x/Public/WWW/TR-Downloads> Options Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny Allow from all RewriteEngine on RewriteBase / RewriteRule ^(.*\.mkv)$ /cgi-bin/mplay.cgi?$1 [R,NC] RewriteRule ^(.*\.mkv).(q.)$ /cgi-bin/mplay.cgi?$1&$2 [R,NC] </Directory> Alias /avs/ "/DataVolume/.avs/" <Directory /DataVolume/.avs/> Options Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny Allow from all </Directory> <Directory /DataVolume/.avs/pl/> RewriteEngine on RewriteBase / RewriteRule ^(.*)\.m3u8$ /cgi-bin/m3u8.cgi?$1 [L] RewriteRule ^segment_(.*)\.ts$ /cgi-bin/ts.cgi?$1 [L] </Directory> ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ <Directory "/usr/lib/cgi-bin"> AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny Allow from all </Directory> ErrorLog /var/log/apache2/avs-error.log LogLevel warn </VirtualHost>

调整mplay.py,把地址换成本地服务器。

vim /usr/lib/cgi-bin/mplay.py

#!/usr/bin/env python
import os
import socket,urllib
try:
    server=os.environ['HTTP_HOST']
except:
    server="192.168.91.4"
try:
    filename=os.environ["QUERY_STRING"]
except:
    filename="share/mbl/Shared%20Videos/2012.09.21.Resident.Evil.Damnation.2012.Blu-ray.720p.x264.DTS.MySilu/Resident.Evil.Damnation.2012.Blu-ray.720p.x264.DTS.MySilu.mkv"
    filename="Public/Shared%20Videos/%e6%96%ad%e7%ae%ad.Broken.Arrow.1996.BluRay.720P.DTS.2Audio.x264-CHD/Broken.Arrow.1996.BluRay.720P.DTS.2Audio.x264-CHD.mkv"

pos=filename.find('&')
arg=''
if pos>=0:
    arg=filename[pos+1:]
    filename=filename[:pos]
filename="/DataVolume/shares/Public/WWW/TR-Downloads/"+urllib.unquote(filename)


s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('127.0.0.1',7890))
if arg=='qa' or arg=='qs':
    if arg=='qa':
        s.send("I%s\n"%filename)
    else:
        s.send("T%s\n"%filename)
    d=s.recv(1024)
    x=list(eval(d))
    length=x[0].strip()
    hour,min,sec=x[0].split(":")
    if sec[-1]==',': sec=sec[:-1]
    alll=int(hour)*3600+int(min)*60+float(sec)
    alll=int(alll)
    ret=[]
    ret.append(alll)
    audios=[]
    try:
        for audline in x[2]:
            info=audline.split("Audio:")
            sid=info[0].split()[1].split('.')[1]
            pos=sid.find("(")
            lang=''
            if pos>=0:
                lang=sid[pos:]
                sid=sid[:pos]
            else:
                if sid[-1]==":":sid=sid[:-1]
            sinfo=lang+info[1].strip()
            audios.append([sid,sinfo])
    except:
        audios=[]
    ret.append(audios)
    if len(x)>3:
        srt=x[3]
        ret.append(srt)
    print "Content-type: text/html\r\n\r\n",
    print str(ret)
else:
    if arg!='':
        filename=filename+'.q'
        if arg[0]=='Q':
            filename=filename+'c'
        else:
            filename=filename+'t'
        filename=filename+arg[1]
    s.send("S%s\n"%filename)
    d=s.recv(1024)
    x=eval(d)
    length=x[0].strip()
    hour,min,sec=x[0].split(":")
    if sec[-1]==',': sec=sec[:-1]
    alll=int(hour)*3600+int(min)*60+float(sec)
    alll=int(alll)
    s.close()
    url='http://%s/avs/pl/%s.m3u8'% (server,alll)
    print "Status: 302 Moved"
    print "Location: %s" % url
    print "URI: %s" % url
    print "Content-type: text/html\r\n\r\n"

增加其他依赖与配置

sed -i "s/AllowOverride None/AllowOverride All/" /etc/apache2/sites-available/wdnas
ln -s /DataVolume/shares/ /var/www/shares
echo "Options +Indexes">/DataVolume/shares/.htaccess
ln -s /DataVolume/shares/appletv /var/www/appletv
echo "Options +Indexes" >/mw2/.htaccess
ln -s /appletv/ /var/www/appletv
echo "Options +Indexes">/appletv/.htaccess
ln -s /DataVolume/shares/media/ /var/www/media
echo "Options +Indexes">/media/.htaccess
ln -s /etc/apache2/mods-available/autoindex.conf /etc/apache2/mods-enabled/
ln -s /etc/apache2/mods-available/autoindex.load /etc/apache2/mods-enabled/

gitlab备份、恢复、迁移

备份

/etc/gitlab/gitlab.rb 文件内的会有gitlab_rails['backup_path']的字段,是存储备份目录,我们可以修改并使用gitlab-ctl reconfigure命令重载生效。

调整好存储备份目录后可以使用下面的命令进行备份:

gitlab-rake gitlab:backup:create

执行后会生成1501724591_2017_08_03_gitlab_backup.tar格式的tar包,其中1501724591为备份编号稍后恢复时需要用到。

恢复

恢复也是非常简单的,但需要先停止gitlab相关服务,把备份好的文件放入存储备份目录后,指定备份编号即可完成恢复

gitlab-ctl stop unicorn
gitlab-ctl stop sidekiq


gitlab-rake gitlab:backup:restore BACKUP=1501724591


sudo gitlab-ctl start

迁移

迁移使用上备份,并把备份文件拷贝到其他设备上进行恢复。

wordpress安装与https配置

安装WordPress

下载并解压WordPress

# 下载
wget -c https://wordpress.org/latest.tar.gz
# 解压
tar -xzvf latest.tar.gz 

安装所需包

yum install php-fpm php-mysql mysql-server php-mbstring php-gd php-pear php-mcrypt php-mhash php-eaccelerator php-suhosin php-tidy php-curl -y

配置数据库,登陆数据库进行如下操作:

# 创建数据库
CREATE DATABASE wordpress;
# 创建专用用户
CREATE USER wordpressuser@localhost;
# 设置密码
SET PASSWORD FOR wordpressuser@localhost= PASSWORD("yourpassword");
# 设置权限
GRANT ALL PRIVILEGES ON wordpress.* TO wordpressuser@localhost IDENTIFIED BY 'yourpassword';
# 更新
FLUSH PRIVILEGES;

修改连接配置文件,增加刚增加的数据库信息。

# 复制sample为配置文件
cp wp-config-sample.php wp-config.php
# 修改配置文件
vim wp-config.php

申请Let’s Encrypt 证书

在配置好nginx后,简单改了改模板样式,正好之前公司项目想配HTTPS,所以紧趁热试一试。

Let’s Encrypt 是个免费、开放的证书签发服务,下面我们就来配置一下。

创建帐号

首选创建rsa帐户

openssl genrsa 4096 > account.key

创建CSR文件

下面生成CSR(Certificate Signing Request)文件,首先创建ECC或RSA私钥

  • RSA私钥(兼容性好):
openssl genrsa 4096 > domain.key
  • 我使用的是ECC私钥:
#secp256r1
openssl ecparam -genkey -name secp256r1 | openssl ec -out domain.key

#secp384r1
openssl ecparam -genkey -name secp384r1 | openssl ec -out domain.key

有了私钥就可以生成CSR,注意把下面的yoursite换成自己的域名。

openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:yoursite.com,DNS:www.yoursite.com")) > domain.csr

配置验证服务

因为需要验证域名所有权,Let’s Encrypt是在域名服务器上访问指定文件进行验证。

修改Nginx

server {
    server_name www.yoursite.com yoursite.com;

    location ^~ /.well-known/acme-challenge/ {
            alias /var/www/challenges/;
            try_files $uri =404;
    }
}

验证并获取证书

这里使用acme-tiny进行申请

wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py

申请

python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir ~/www/challenges/ > ./signed.crt

下载根证书和中间证书并合并

wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem
wget -O - https://letsencrypt.org/certs/isrgrootx1.pem > root.pem
cat intermediate.pem root.pem > full_chained.pem

服务器需要用到的chained.pemdomain.key就生成好了,可以去配置服务器了。

配置服务器

我使用的是Nginx,配置的过程还是比较痛苦的,因为服务器防火墙抗了半日。

/etc/nginx/conf.d/virtual.conf主要配置了验证申请证书服务,并把所有http跳到https。

server {  
    listen 80;  
    server_name yoursite.com www.yoursite.com;
    location ^~ /.well-known/acme-challenge/ {
            alias /var/www/challenges/;
            try_files $uri =404;
        }

    location / {
        rewrite ^/(.*)$ https://qiknow.com/$1 permanent;
    }
}

/etc/nginx/conf.d/ssl.conf配置了WordPress环境,并ssl_certificate /etc/ssl/chained.pem;ssl_certificate_key /etc/ssl/domain.key;还指定生成的证书文件。

server {
    listen       443 ssl http2 default_server;
    listen       [::]:443 ssl;
    server_name  yoursite.com www.yoursite.com;
    root         /var/www/wordpress;
    index index.php index.html index.htm;

    ssl_certificate /etc/ssl/chained.pem;
    ssl_certificate_key /etc/ssl/domain.key;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  10m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;


    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
    location / {
        try_files $uri $uri/ /index.php?$args ;
    }
    location ~ \.php$ {
                root           /var/www/wordpress;
                fastcgi_pass   127.0.0.1:9000;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME      $document_root$fastcgi_script_name;
                include        fastcgi_params;
    }
}

更新证书

用了一段时间会过期,需要更新证书,步骤如下:


python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /var/www/challenges/ > ./signed2.crt wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate2.pem cat signed2.crt intermediate2.pem > chained2.pem wget -O - https://letsencrypt.org/certs/isrgrootx1.pem > root2.pem cat intermediate2.pem root2.pem > full_chained2.pem mv /etc/ssl/chained.pem /etc/ssl/chained.pem.bak cp chained2.pem /etc/ssl/chained.pem service nginx restart

如何写出让人一看就懂的邮件—信息化

前文提到如何使用我们内容更具逻辑性,与如何使内容剧情化,让对方感兴趣,这节我们再讲述三个方面进一步对内容优化,提高沟通效率。

排除重复内容

我们在讲述内容的时间经常会把理所当然的事情说得冠冕堂皇,觉得很高深、很有道理,其实对接受者毫无意义。这是种正确的废话,我们应该避免使用这样的词或句子。如:贯彻、强化。

表明立场

我们一定要清楚的让接受者明白我们的立场,是赞成还是反对。我们可以使用否定斩断退路。通过否定明确地表达立场,也可通过相对柔弱否定来表达。
– 我们不需要延长工作时间,而是要提高工作效率。(强)
– 我们要从延长工作时间变为提高工作效率。(弱)

把形容词和副词换成数字

数字可以更明确的传递信息给对方。当我们把想要表达的内容 数字进行思考时,可以使我们重新审视自己拥有的。从另外一个方面来考虑:所有事物都需要一定的量化,不设置”状态“与”期限“的目标都是伪目标。