分类 我爱编程 下的文章

Let’s Encrypt自动续期脚本

原文参考:https://www.zivers.com/post/492.html

 

首先复制Let’s Encrypt的样例cli文件

去除以下字段前的注释并对配置文件进行修改:

现在,你可以用配置化的命令执行更新操作

创建自动更新脚本

于是我们可以创建一个脚本来自动执行上述操作

样例脚本如下:

赋予执行权限

免费 Https 证书(Let'S Encrypt)申请与配置

原文:https://keelii.github.io/2016/06/12/free-https-cert-lets-encrypt-apply-install/

1. 下载 certbot

git clone https://github.com/certbot/certbot
cd certbot
./certbot-auto --help

解压打开执行就会有相关提示

2. 生成免费证书

./certbot-auto certonly --webroot --agree-tos -v -t --email 邮箱地址 -w 网站根目录 -d 网站域名
./certbot-auto certonly --webroot --agree-tos -v -t --email keeliizhou@gmail.com -w /path/to/your/web/root -d note.crazy4code.com

注意 这里 默认会自动生成 /网站根目录/.well-known/acme-challenge,然后 shell 脚本会对应的访问 网站域名/.well-known/acme-challenge

如果返回正常就确认了你对这个网站的所有权,就能顺利生成

3. 获取证书

如果上面的步骤正常 shell 脚本会展示如下信息:

- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/网站域名/fullchain.pem
...

4. 生成 dhparams

使用 openssl 工具生成 dhparams

openssl dhparam -out /etc/ssl/certs/dhparams.pem 2048

5. 配置 Nginx

打开 nginx server 配置文件加入如下设置:

listen 443

ssl on;
ssl_certificate /etc/letsencrypt/live/网站域名/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/网站域名/privkey.pem;
ssl_dhparam /etc/ssl/certs/dhparams.pem;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;

然后重启 nginx 服务就可以了

6. 强制跳转 https

https 默认是监听 443 端口的,没开启 https 访问的话一般默认是 80 端口。如果你确定网站 80 端口上的站点都支持 https 的话加入下面的配件可以自动重定向到 https

server {
    listen 80;
    server_name your.domain.com;
    return 301 https://$server_name$request_uri;
}

7. 证书更新

免费证书只有 90 天的有效期,到时需要手动更新 renew。刚好 Let’s encrypt 旗下还有一个 Let’s monitor 免费服务,注册账号添加需要监控的域名,系统会在证书马上到期时发出提醒邮件,非常方便。收到邮件后去后台执行 renew 即可,如果提示成功就表示 renew 成功

./certbot-auto renew

YII relations condition和on的区别

观察以下分别用condition和on的语句
condition:
SELECT `t`.`id` AS `t0_c0`, `t`.`fdName` AS `t0_c1`,
`t`.`fdEnglish` AS `t0_c2`, `t`.`fdTypeID` AS `t0_c3`, `t`.`fdKindID` AS
`t0_c4`, `t`.`fdAcronym` AS `t0_c5`, `t`.`fdPinyin` AS `t0_c6`,
`t`.`fdProviderID` AS `t0_c7`, `t`.`fdCpID` AS `t0_c8`, `t`.`fdOperatorID`
AS `t0_c9`, `t`.`fdApproverID` AS `t0_c10`, `t`.`fdApprove` AS `t0_c11`,
`t`.`fdCreate` AS `t0_c12`, `t`.`fdExpire` AS `t0_c13`, `t`.`fdModify` AS
`t0_c14`, `t`.`fdAdapt` AS `t0_c15`, `t`.`fdHot` AS `t0_c16`,
`t`.`fdBornID` AS `t0_c17`, `t`.`fdSync` AS `t0_c18`, `t`.`fdCommentID` AS
`t0_c19`, `t`.`fdDisabled` AS `t0_c20`, `quality`.`id` AS `t1_c0`,
`quality`.`fdContentID` AS `t1_c1`, `quality`.`fdFileID` AS `t1_c2`,
`quality`.`fdAttributeID` AS `t1_c3`, `quality`.`fdSourceID` AS `t1_c4`,
`quality`.`fdValue` AS `t1_c5`, `playNum`.`id` AS `t2_c0`,
`playNum`.`fdContentID` AS `t2_c1`, `playNum`.`fdFileID` AS `t2_c2`,
`playNum`.`fdAttributeID` AS `t2_c3`, `playNum`.`fdSourceID` AS `t2_c4`,
`playNum`.`fdValue` AS `t2_c5`, `perpareAttrID`.`id` AS `t3_c0`,
`perpareAttrID`.`fdContentID` AS `t3_c1`, `perpareAttrID`.`fdFileID` AS
`t3_c2`, `perpareAttrID`.`fdAttributeID` AS `t3_c3`,
`perpareAttrID`.`fdSourceID` AS `t3_c4`, `perpareAttrID`.`fdValue` AS
`t3_c5` FROM `keti2ctn`.`tbContent` `t` LEFT OUTER JOIN
`keti2ctn`.`tbInteger` `quality` ON (`quality`.`fdContentID`=`t`.`id`) AND
(quality.fdAttributeID=360) LEFT OUTER JOIN `keti2ctn`.`tbInteger`
`playNum` ON (`playNum`.`fdContentID`=`t`.`id`) LEFT OUTER JOIN
`keti2ctn`.`tbInteger` `perpareAttrID` ON
(`perpareAttrID`.`fdContentID`=`t`.`id`) WHERE ((t.fdTypeID IN (:ycp0,
:ycp1, :ycp2, :ycp3, :ycp4)) AND (perpareAttrID.fdValue is null)) AND
(playNum.fdAttributeID=50) AND (perpareAttrID.fdAttributeID=386) ORDER BY
t.id desc LIMIT 10
on:
SELECT `t`.`id` AS `t0_c0`, `t`.`fdName` AS `t0_c1`,
`t`.`fdEnglish` AS `t0_c2`, `t`.`fdTypeID` AS `t0_c3`, `t`.`fdKindID` AS
`t0_c4`, `t`.`fdAcronym` AS `t0_c5`, `t`.`fdPinyin` AS `t0_c6`,
`t`.`fdProviderID` AS `t0_c7`, `t`.`fdCpID` AS `t0_c8`, `t`.`fdOperatorID`
AS `t0_c9`, `t`.`fdApproverID` AS `t0_c10`, `t`.`fdApprove` AS `t0_c11`,
`t`.`fdCreate` AS `t0_c12`, `t`.`fdExpire` AS `t0_c13`, `t`.`fdModify` AS
`t0_c14`, `t`.`fdAdapt` AS `t0_c15`, `t`.`fdHot` AS `t0_c16`,
`t`.`fdBornID` AS `t0_c17`, `t`.`fdSync` AS `t0_c18`, `t`.`fdCommentID` AS
`t0_c19`, `t`.`fdDisabled` AS `t0_c20`, `quality`.`id` AS `t1_c0`,
`quality`.`fdContentID` AS `t1_c1`, `quality`.`fdFileID` AS `t1_c2`,
`quality`.`fdAttributeID` AS `t1_c3`, `quality`.`fdSourceID` AS `t1_c4`,
`quality`.`fdValue` AS `t1_c5`, `playNum`.`id` AS `t2_c0`,
`playNum`.`fdContentID` AS `t2_c1`, `playNum`.`fdFileID` AS `t2_c2`,
`playNum`.`fdAttributeID` AS `t2_c3`, `playNum`.`fdSourceID` AS `t2_c4`,
`playNum`.`fdValue` AS `t2_c5`, `perpareAttrID`.`id` AS `t3_c0`,
`perpareAttrID`.`fdContentID` AS `t3_c1`, `perpareAttrID`.`fdFileID` AS
`t3_c2`, `perpareAttrID`.`fdAttributeID` AS `t3_c3`,
`perpareAttrID`.`fdSourceID` AS `t3_c4`, `perpareAttrID`.`fdValue` AS
`t3_c5` FROM `keti2ctn`.`tbContent` `t` LEFT OUTER JOIN
`keti2ctn`.`tbInteger` `quality` ON (`quality`.`fdContentID`=`t`.`id`) AND
(quality.fdAttributeID=360) LEFT OUTER JOIN `keti2ctn`.`tbInteger`
`playNum` ON (`playNum`.`fdContentID`=`t`.`id`) LEFT OUTER JOIN
`keti2ctn`.`tbInteger` `perpareAttrID` ON
(`perpareAttrID`.`fdContentID`=`t`.`id`) AND
(perpareAttrID.fdAttributeID=386) WHERE ((t.fdTypeID IN (:ycp0, :ycp1,
:ycp2, :ycp3, :ycp4)) AND (perpareAttrID.fdValue is null)) AND
(playNum.fdAttributeID=50) ORDER BY t.id desc LIMIT 10
观察上述语句,不难看出当用condition的时候关联表的时候,AND (perpareAttrID.fdAttributeID=386) 作为联表后where的条件限制,
而用on的时候则是作为联表限制。

ThinkPHP&&YII1 UEditor 添加在线图片&&在线附件删除功能

TP框架请参考以下:

第一,需要添加一个 php 文件来实现删除功能,文件添加到:ueditor\php\action_delete.php 代码内容:

<?php
/*---------------------------
* Flyヽ
* http://lfei.org
* 2016-02-04
* action_delete.php
* 删除 Ueditor 目录下的文件
*---------------------------*/
try {
    //获取路径
    $path = $_POST['path'];
    $path = str_replace('../', '', $path);
    $path = str_replace('/', '\\', $path);
    
    //安全判断(只允许删除 ueditor 目录下的文件)
    if(stripos($path, '\\ueditor\\') !== 0)
    {
        return '非法删除';
    }
    
    //获取完整路径
    $path = $_SERVER['DOCUMENT_ROOT'].$path;
    if(file_exists($path)) {
        //删除文件
        unlink($path);
        return 'ok';
    } else {
        return '删除失败,未找到'.$path;
    }
} catch (Exception $e) {
    return '删除异常:'.$e->getMessage();
}


第二,需要在 ueditor\php\controller.php 文件的 switch 中添加命令 deleteimage 的处理:

....
switch ($action) {
    ....
  
    /* 删除图片命令处理 */
    case 'deleteimage':
         $result = include('action_delete.php');
         break;
    
    /* 在 default 之前添加 */
    default:
        $result = json_encode(array(
            'state'=> '请求地址出错'
        ));
        break;
}
....


第三,在图片上添加删除按钮,需要修改 Js 文件:ueditor\dialogs\image\image.js

....
/* 在这两句之后添加 */
item.appendChild(img);
item.appendChild(icon);
/* 添加删除功能 */
item.appendChild($("<span class='delbtn' url='" + list[i].url + "'>✖</span>").click(function() {
    var del = $(this);
    try{
        window.event.cancelBubble = true; //停止冒泡
        window.event.returnValue = false; //阻止事件的默认行为
        window.event.preventDefault();    //取消事件的默认行为  
        window.event.stopPropagation();   //阻止事件的传播
    } finally {
        if(!confirm("确定要删除吗?")) return;
        $.post(editor.getOpt("serverUrl") + "?action=deleteimage", { "path": del.attr("url") }, function(result) {
            if (result == "ok") del.parent().remove();
            else alert(result);
        });
    }
})[0]);
/* 在这一句之前添加 */
this.list.insertBefore(item, this.clearFloat);
....


第四,为删除按钮添加一个样式,修改文件:ueditor\dialogs\image\image.css 在最底部添加如下代码:

/* 在线管理删除按钮样式 */
#online li .delbtn {      
    position: absolute;
    top: 0;
    right: 0;
    border: 0;  
    z-index: 3;
    color: #ffffff;
    display: inline;
    font-size: 12px;
    line-height: 10.5px;
    padding:3px 5px;
    text-align: center;
    background-color: #d9534f;
}

以上教程转载:http://lfei.org/ueditor-manage-image-delete/


若需要增加鼠标滑动显示删除按钮及在线附件删除功能请参考以下:

打开ueditor\dialogs\image\image.js找到

this.list.insertBefore(item, this.clearFloat);

在这句语句的下面插入:

/* 添加删除按钮滑动事件 */
$(item).mouseenter(function () {
    $(this).find('.delbtn').css('display','block');
}).mouseleave(function(){
    $(this).find('.delbtn').css('display','none');
});

添加附件删除功能:

打开ueditor\dialogs\attachment\attachment.js找到

item.appendChild(icon);

在次句语句下添加:

item.appendChild($("<span class='delbtn' style='display:none;' url='" + list[i].url + "'>✖</span>").click(function() {
    var del = $(this);
    try{
        window.event.cancelBubble = true; //停止冒泡
        window.event.returnValue = false; //阻止事件的默认行为
        window.event.preventDefault();    //取消事件的默认行为
        window.event.stopPropagation();   //阻止事件的传播
    } finally {
        if(!confirm("确定要删除吗?")) return;
        $.post(editor.getOpt("serverUrl") + "&action=deleteimage", { "path": del.attr("url") }, function(result) {
            if (result == "ok") del.parent().remove();
            else alert(result);
        });
    }
})[0]);

/* 添加删除按钮滑动事件 */
$(item).mouseenter(function () {
    $(this).find('.delbtn').css('display','block');
}).mouseleave(function(){
    $(this).find('.delbtn').css('display','none');
});

打开ueditor\dialogs\attachment\attachment.css在最底部添加如下代码:

/* 在线管理删除按钮样式 */
#online li .delbtn {      
    position: absolute;
    top: 0;
    right: 0;
    border: 0;  
    z-index: 3;
    color: #ffffff;
    display: inline;
    font-size: 12px;
    line-height: 10.5px;
    padding:3px 5px;
    text-align: center;
    background-color: #d9534f;
}

'application.extensions.baiduUeditor.*',在线图片效果如下:

在线附件效果如下:

 
 

YII Ueditor包下载地址:https://github.com/q250305917/Ueditor-for-YII1

下载后解压放在\protected\extensions\下

   

 打开main.php配置文件,在import里面增加:


 

将\protected\extensions\baiduUeditor\UeditorController.php拷贝至模块控制器中,在视图页面绑定使用参考:

<?php
//KindEditor
$this->widget('ext.baiduUeditor.UeditorWidget',
    array(
        'id'=>'NoticeFormV3_text',//容器的id 唯一的[必须配置]
        'name'=>'content',//post到后台接收的name [必须配置]
        'content'=>'',//初始化内容 [可选的]
        //配置选项,[可选的]
        //将ueditor的配置项以数组键值对的方式传入,具体查看ueditor.config.js
        //不要配置serverUrl(即使配置也会被覆盖)程序会自动处理后端url
        'config'=>array(
            'wordCount'=>false,
            'elementPathEnabled'=>false,
            "imageAllowFiles"=> array(".png", ".jpg", ".jpeg", ".gif", ".bmp"),
            'toolbars'=>array(array('fontfamily', 'fontsize', 'forecolor', 'backcolor','|',
                'indent', '|',
                'fullscreen','|',
                'bold', 'italic', 'underline','autotypeset', '|',
                'customstyle',
                'paragraph', '|',
                'link', 'unlink', '|', 'imagenone', 'imageleft', 'imageright',
                'imagecenter', '|','simpleupload','insertimage', 'emotion', 'insertvideo', 'attachment',)),//toolbars注意是嵌套两个数组
            'lang'=>'zh-cn'
        )
    )
); ?>

错误排除


  • 出现错误首先应该打开调试工具查看请求返回具体信息。


  • 因为编辑器通常使用场景为后台,所以图片上传等功能默认需要登录权限,如果不需要可以自行修改。


  • 默认上传路径为「应用根目录」,而不是网站根目录,如果上传失败请查看目录权限。


  • 不要开启Yii的调试,因为UEditor的返回都是json格式,开启调试会导致返回格式不识别。


  • 出现404错误可能是因为widget没有正确配置serverUrl。

 

上传错误提示:后端配置项没有正常加载,上传插件不能正常使用!检查Yii是否开启调试,关闭调试,检查初始化UeditorController中用户是否具有访问权限

 

/*        if(Yii::app()->user->isGuest){
            echo json_encode(array('state'=>'没有权限'));
            Yii::app()->end();
        }*/

注释所有权限设置,重新打开上传页面,判断是否权限阻止上传

Nginx开启支持pathinfo模式

配置nginx,支持php的pathinfo路径模式
nginx模式默认是不支持pathinfo模式的,类似index.php/index形式的url会被提示找不到页面。下面的通过正则找出实际文件路径和pathinfo部分的方法,让nginx支持pathinfo。
本文基于安装lnmp一键安装包,添加虚拟主机情况下进行修改。如你要添加一个网站www.linuxeye.com支持pathinfo,配置文件nginx.conf不用任何改变(个人习惯),参考lnmp一键安装包
cat vhost/www.linuxeye.com.conf
server {
listen  80;
server_name     www.linuxeye.com;
access_log  logs/www.linuxeye.com.log combined;
root /home/wwwroot/www.linuxeye.com;
error_page  404  /404.html;
index index.html index.htm index.php ;
location / {
        index  index.php;
        if (!-e $request_filename) {
        rewrite  ^/(.*)$  /index.php/$1  last;
        break;
        }
}
location ~ \.php {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi_pathinfo.conf;
set $real_script_name $fastcgi_script_name;
    if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
    set $real_script_name $1;
    set $path_info $2;
        }
fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
fastcgi_param SCRIPT_NAME $real_script_name;
fastcgi_param PATH_INFO $path_info;
        }
}
要点:
1.~ \.php 后面不能有$  以便能匹配所有 *.php/* 形式的url
2. 通过设置更改 SCRIPT_FILENAME
cat fcgi_pathinfo.conf
#fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
#fastcgi_param  SCRIPT_NAME        $fastcgi_script_name; #这两行是需要注释掉的,请注意
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  HTTPS              $https if_not_empty;
fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;
以LNMP为例若以上办法依然不能解决:
增加一行include enable-php-pathinfo.conf;
删除include fcgi_pathinfo.conf;
server
{
listen 80;
#listen [::]:80;
server_name y-yun.top;
index index.html index.htm index.php default.html default.htm default.php;
root /home/wwwroot/y-yun.top/wordpress;
include other.conf;
#error_page 404 /404.html;
include enable-php-pathinfo.conf;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 12h;
}
location ~ /\.
{
deny all;
}
location / {
index index.php;
if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php/$1 last;
break;
}
}
location ~ \.php {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
#include fcgi_pathinfo.conf;
set $real_script_name $fastcgi_script_name;
if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
set $real_script_name $1;
set $path_info $2;
}
fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
fastcgi_param SCRIPT_NAME $real_script_name;
fastcgi_param PATH_INFO $path_info;
}
access_log /home/wwwlogs/www.markss.xyz.log;
}
以上部分参考转载www.linuxeye.com