Akawa

ETY001的博客

使用 yaourt 安装 frp 的时候,报告以下的错误:

1
2
3
4
5
6
7
==> Validating source files with sha256sums...
frps.service ... FAILED
frpc.service ... FAILED
frps@.service ... FAILED
frpc@.service ... FAILED
==> ERROR: One or more files did not pass the validity check!
:: failed to verify frp integrity

解决方案,重新自己生成 PKGBUILD 文件:

1
2
3
4
5
$ yaourt -G frp
$ cd frp
$ makepkg -g >> PKGBUILD
$ makepkg
$ sudo pacman -S frp-0.14.0-2-x86_64.pkg.tar.xz

使用方法:

1
2
3
4
5
6
7
8
9
To start the client, simply modify /etc/frp/frpc.ini, and start the service by:

systemctl start frpc

or create your own config file, for example myconf.ini, and start the service by:

systemctl start frpc@myconf

You can also start frps the same way

具体配置参数见 https://github.com/fatedier/frp

今天配置服务器的https,结果配置完后,浏览器访问报错,显示

1
2
This site can’t provide a secure connection
1hour.win sent an invalid response.

openssl 看了下,发现报错如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[root@host wwwroot]# openssl s_client -connect 1hour.win:443 -debug
CONNECTED(00000003)
write to 0x1d66480 [0x1e64440] (247 bytes => 247 (0xF7))
0000 - 16 03 01 00 f2 01 00 00-ee 03 03 59 77 63 d6 28 ...........Ywc.(
0010 - 1e d6 5a c6 ba ef 29 51-7a 37 7f 93 4b 6d 05 e1 ..Z...)Qz7..Km..
0020 - 1c 45 37 ba c2 11 3e 12-1d 36 2a 00 00 84 c0 30 .E7...>..6*....0
0030 - c0 2c c0 28 c0 24 c0 14-c0 0a 00 a3 00 9f 00 6b .,.(.$.........k
0040 - 00 6a 00 39 00 38 00 88-00 87 c0 32 c0 2e c0 2a .j.9.8.....2...*
0050 - c0 26 c0 0f c0 05 00 9d-00 3d 00 35 00 84 c0 2f .&.......=.5.../
0060 - c0 2b c0 27 c0 23 c0 13-c0 09 00 a2 00 9e 00 67 .+.'.#.........g
0070 - 00 40 00 33 00 32 00 9a-00 99 00 45 00 44 c0 31 .@.3.2.....E.D.1
0080 - c0 2d c0 29 c0 25 c0 0e-c0 04 00 9c 00 3c 00 2f .-.).%.......<./
0090 - 00 96 00 41 c0 12 c0 08-00 16 00 13 c0 0d c0 03 ...A............
00a0 - 00 0a 00 07 c0 11 c0 07-c0 0c c0 02 00 05 00 04 ................
00b0 - 00 ff 01 00 00 41 00 0b-00 04 03 00 01 02 00 0a .....A..........
00c0 - 00 08 00 06 00 19 00 18-00 17 00 23 00 00 00 0d ...........#....
00d0 - 00 20 00 1e 06 01 06 02-06 03 05 01 05 02 05 03 . ..............
00e0 - 04 01 04 02 04 03 03 01-03 02 03 03 02 01 02 02 ................
00f0 - 02 03 00 0f 00 01 01 .......
read from 0x1d66480 [0x1e699a0] (7 bytes => 7 (0x7))
0000 - 48 54 54 50 2f 31 2e HTTP/1.
140304408045472:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:769:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 247 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

unknown protocol? 这是啥情况,仔细比对配置,发现原来是在 listen 配置项中掉了 ssl
正确配置应该是

1
listen 443 ssl;

之前写成了

1
listen 443;

在服务器端部署代码的时候,新版本的 composer 不再支持 root 用户来运行。因为会带来潜在的安全问题,
这导致 composer update 之后,不会再执行 scripts 里的脚本命令。

但是一般服务器上的web服务都是运行在 www 之类的用户下面的,且这些用户是不允许登陆的,那么我们该咋整?

经过搜索和实验后,发现 runuser 不好使,可以使用 sudo,具体命令如下:

1
sudo -u www /usr/local/bin/composer update
注意要执行的命令需要完整路径。

最近需要做一个快速上线的项目,要求使用 Symfony 框架。

久闻 SymfonyBundle 很丰富,于是搜索了下现成的后台系统。
首先发现的是 Sonata Admin Panel,是个老牌的系统了,可惜经过研究发现,
它对于 Symfony3 下的新版本的 FOS Bundle(一个用户系统) 不支持。于是又找了一个,
名字是 EasyAdminBundle

这篇博客会用最短最快的方式,让你建立一个简易的博客后台,其中的各个步骤则不解释。

体验环境:MacOS X 或 Linux (注意 phppdo_mysql.so 请打开)

  • 安装 Symfony

    1
    2
    3
    $ sudo mkdir -p /usr/local/bin
    $ sudo curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony
    $ sudo chmod a+x /usr/local/bin/symfony
  • 创建 Symfony 项目 并启动服务

    1
    2
    3
    $ symfony new blog
    $ cd blog
    $ php bin/console server:start

访问下 http://127.0.0.1:8000 看是否正常启动。

  • 如需停止服务,执行下面的命令

    1
    $ php bin/console server:stop
  • 下载安装 EasyAdmin

    1
    $ composer require javiereguiluz/easyadmin-bundle
  • 激活插件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?php
    // app/AppKernel.php
    // ...
    class AppKernel extends Kernel
    {
    public function registerBundles()
    {
    $bundles = array(
    // ...
    new JavierEguiluz\Bundle\EasyAdminBundle\EasyAdminBundle(),
    );
    }
    // ...
    }
  • 载入路由

    1
    2
    3
    4
    5
    # app/config/routing.yml
    easy_admin_bundle:
    resource: "@EasyAdminBundle/Controller/"
    type: annotation
    prefix: /admin
  • 载入静态资源

    1
    2
    # Symfony 3
    php bin/console assets:install --symlink
  • app/config/parameters.yml 中配置数据库连接

  • 创建 Entity

    1
    2
    $ php bin/console doctrine:generate:entity --entity="AppBundle:Category" --fields="name:string(255) enabled:boolean" --no-interaction
    $ php bin/console doctrine:generate:entity --entity="AppBundle:Posts" --fields="title:string(255) contents:text() enabled:boolean" --no-interaction
  • src/AppBundle/Entity/PostsEntity.php 中增加关联关系

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php
    // ...
    class Posts
    {
    // ...
    /**
    * @ORM\ManyToOne(targetEntity="Category", inversedBy="posts")
    * @ORM\JoinColumn(name="category_id", referencedColumnName="id")
    */
    private $category;
    }
  • src/AppBundle/Entity/Category.php 中增加对应的关联关系(新增代码如下)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // src/AppBundle/Entity/Category.php

    // ...
    use Doctrine\Common\Collections\ArrayCollection;

    class Category
    {
    // ...

    /**
    * @ORM\OneToMany(targetEntity="Posts", mappedBy="category")
    */
    private $posts;

    public function __construct()
    {
    $this->posts = new ArrayCollection();
    }
    }
  • 执行以下命令,完善对应属性的方法

    1
    2
    $ composer update
    $ php bin/console doctrine:generate:entities AppBundle --no-backup
  • 执行以下命令,生成数据表

    1
    $ php bin/console doctrine:schema:update --force
  • 配置后台

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # app/config/config.yml
    easy_admin:
    entities:
    Category:
    class: AppBundle\Entity\Category
    form:
    fields:
    - name
    Posts:
    class: AppBundle\Entity\Posts
    form:
    fields:
    - title
    - { property: 'category', type: 'easyadmin_autocomplete' }
    - contents
  • 配置语言

    1
    2
    3
    # app/config/config.yml
    framework:
    translator: { fallbacks: ['%locale%'] }

这时,访问 http://127.0.0.1:8000/admin,就能看到我们的后台了。

下面是集成 FOS Bundle 的操作。

  1. 安装 FOS

    1
    $ composer require friendsofsymfony/user-bundle "~2.0"
  2. 启用 FOS

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php
    // app/AppKernel.php

    public function registerBundles()
    {
    $bundles = array(
    // ...
    new FOS\UserBundle\FOSUserBundle(),
    // ...
    );
    }
  3. 创建 User Class

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <?php
    // src/AppBundle/Entity/User.php

    namespace AppBundle\Entity;

    use FOS\UserBundle\Model\User as BaseUser;
    use Doctrine\ORM\Mapping as ORM;

    /**
    * @ORM\Entity
    * @ORM\Table(name="fos_user")
    */
    class User extends BaseUser
    {
    /**
    * @ORM\Id
    * @ORM\Column(type="integer")
    * @ORM\GeneratedValue(strategy="AUTO")
    */
    protected $id;

    public function __construct()
    {
    parent::__construct();
    // your own logic
    }
    }
  4. 增加防火墙配置(全部替换原有内容)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    # app/config/security.yml
    security:
    encoders:
    FOS\UserBundle\Model\UserInterface: bcrypt

    role_hierarchy:
    ROLE_ADMIN: ROLE_USER
    ROLE_SUPER_ADMIN: ROLE_ADMIN

    providers:
    fos_userbundle:
    id: fos_user.user_provider.username

    firewalls:
    main:
    pattern: ^/
    form_login:
    provider: fos_userbundle
    csrf_token_generator: security.csrf.token_manager
    # if you are using Symfony < 2.8, use the following config instead:
    # csrf_provider: form.csrf_provider

    logout: true
    anonymous: true

    access_control:
    - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/admin/, role: ROLE_ADMIN }
  5. 配置 FOS

    1
    2
    3
    4
    5
    6
    7
    8
    # app/config/config.yml
    fos_user:
    db_driver: orm # other valid values are 'mongodb' and 'couchdb'
    firewall_name: main
    user_class: AppBundle\Entity\User
    from_email:
    address: "%mailer_user%"
    sender_name: "%mailer_user%"
  6. app/config/parameters.yml 中配置第5步中的 mailer_user 参数

  7. 导入 FOS 的路由配置

    1
    2
    3
    # app/config/routing.yml
    fos_user:
    resource: "@FOSUserBundle/Resources/config/routing/all.xml"
  8. 更新数据库

    1
    $ php bin/console doctrine:schema:update --force
  9. 创建新的控制器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // src/AppBundle/Controller/AdminController.php
    namespace AppBundle\Controller;

    use JavierEguiluz\Bundle\EasyAdminBundle\Controller\AdminController as BaseAdminController;

    class AdminController extends BaseAdminController
    {
    public function createNewUserEntity()
    {
    return $this->get('fos_user.user_manager')->createUser();
    }

    public function prePersistUserEntity($user)
    {
    $this->get('fos_user.user_manager')->updateUser($user, false);
    }

    public function preUpdateUserEntity($user)
    {
    $this->get('fos_user.user_manager')->updateUser($user, false);
    }
    }
  10. 在 config.yml 中增加 User 的配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    easy_admin:
    entities:
    User:
    class: AppBundle\Entity\User
    form:
    fields:
    - username
    - email
    - enabled
    - lastLogin
    # if administrators are allowed to edit users' passwords and roles, add this:
    - { property: 'plainPassword', type: 'text', type_options: { required: false } }
    - { property: 'roles', type: 'choice', type_options: { multiple: true, choices: { 'ROLE_USER': 'ROLE_USER', 'ROLE_ADMIN': 'ROLE_ADMIN' } } }

此时你再访问的时候,就会弹出来一个很丑的登陆界面(因为FOS默认不带皮肤)。
使用下面的命令创建一个管理员账号

1
$ php bin/console fos:user:create admin --super-admin

按照提示,即可完成管理员创建的工作。回到网页上,登陆即可。

至此,一个简单的后台就搭建完毕了。

接下来还有很多的工作可以做,这个以后再来完善补充。

  1. composer 更新代码

    1
    php composer.phar install --no-dev --optimize-autoloader
  2. Symfony 清空cache

    1
    php bin/console cache:clear --env=prod --no-debug
  3. 生成 Assets

    1
    php bin/console assetic:dump --env=prod --no-debug

其他的总结

1
2
rm -rf bin/cache/* #手动清空缓存
php bin/console route:debug # 查看哪些路由已经注册

最近好几个服务器,ssh登录的时候,都有同一个报错,

1
setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or directory

经过搜索,找到了解决方案

1
2
3
4
5
6
7
8
9
# tee /etc/environment <<- 'EOF'
LANG=en_US.utf-8
LC_ALL=en_US.utf-8
EOF

# source /etc/environment

/* 生成 en_US.UTF-8 locale文件 CentOS没有locale-gen命令*/
# localedef -v -c -i en_US -f UTF-8 en_US.UTF-8

起因,在代码上线过程中发现了一个bug,列表中缺失的值为 NULL 的记录。
于是检查 SQL 语句,自己感觉没有什么问题。就是列表中不要显示值为 sample 的记录。

原有的SQL大致是这么写的

1
select * from tableA where key != 'sample';

其中还有很多 keyNULL 的记录没有检索出来。

经过搜索引擎的查找,发现原来普通的运算符不能用在 NULL 上。。。

真是惭愧。。居然不知道这个。。。

改为下面的语句后就可以了

1
select * from tableA where key != 'sample' or key is null;

昨天项目中的一个js的时间间隔计算的bug,真的是被搞的焦头烂额。
最终无奈,只能把js计算过程中的每一步都 console.log 出来,
然后才发现,原来是同事的机器本地时间涉及到冬令时和夏令时。

源代码大致是这样:

1
2
3
4
5
6
7
var start_date = '2017/02/10';
var end_date = '2017/05/20';
var tmp = new Date(start_date);
start_time = tmp.getTime();
tmp = new Date(end_date);
end_time = tmp.getTime();
//时间戳相减求间隔的代码就不写了。。。

由于存在夏令时和冬令时的缘故,两次的 tmp 对象的时区其实是不一样的,
这就导致最终的时间戳做差就会少一天。

最终的解决方案是,把时间都统一到 UTC 后,然后再计算。

具体的获取时间戳的方法是:

1
var timestamp = Date.UTC(year, month-1, day);

一定要注意的是 js 中的 month 是从 0 开始的!!!

本打算在从清迈回国的路上,把年终总结写了,结果也是因为懒的可以了,也就放弃了。
回来后一直在忙着各种聚会,也就放下了,好在现在又能挤出时间来完整这篇总结。

2016年是最繁忙的一年了,也是人生最重要的一年。这一年无论是生活还是工作,都有比较多的事情发生。

首先,结婚了,不再单身。这意味以前一个人吃饱即可万事大吉的生活不再返了。新的开始,新的责任,
新的生活。一切都在新的节奏中慢慢去调整自己,适应当前的生活。

最大的感受可能就是个人研究东西的时间大幅减少了。再就是做一些决定的时候,要考虑担忧的方面也多起来了。
这也许就是一种成长。我们不可能永远都是个孩子,总有一天要长大,亲自挑起自己该肩负的担子。

现在回想之前的创业,就觉得的确是做什么事情要趁年轻呀。无论是在精力还是时间方面,都有很大的优势。
越长大,可能羁绊就越多了。

而我就是在这种羁绊的状态中,思考着工作的下一步该如何进展。

总结一年下来的工作,只能用碌碌无为而形容。而过去的多年,现在来看也算称得上碌碌无为了。
工作近5年了,但感觉自己进步甚微,不得不感慨,有个指路人的必要性。有时候,也许指路人的一句话,
就可以点醒自己,或者让自己少走弯路,而我却很少碰到这样的指路人。

越是焦急反而就越是混乱,真的不知道,这样状态什么时候是个了结。

当下,无论做什么,都感觉心有余而力不足。经常的去开导别人的我,现在回过头来看看自己,才发觉自己
才是个可笑之人。只能说,自己想办法开导开导自己,让自己快点走出泥潭吧。

2017,是乱?是迷?还是破?

最近重新把我的Dell本换回了 Archlinux,不过安装了 chrome 后发现 flash 插件不能正常使用。
使用 chrome://plugins 看到 flashlocationinternal-not-yet-present
这应该是没有安装的样子。从 google 上搜索了下,发现 chrome 不再自带 flash 插件了,
需要自己安装。。。

找了下方法,首先需要翻越 GFW,方法可以是 VPN,也可以 shadowsocks。使用代理的话,
在命令行里执行下面的命令:

1
$ google-chrome-stable --proxy-server="127.0.0.1:8888"

默认使用 http代理。打开 chrome 后,访问 chrome://components
点击 Flash 下面的检查更新,之后就可以安装成功了。

0%