Debian stretch安装nvidia显卡驱动,并配置双显卡切换

机器是戴尔老爷机,Dell inspiron 14r 7420,显卡为Intel + Nvidia。

之前Debian wheezy上双显卡解决方案见我的这篇。建议先阅读该篇。

下面是我解决问题之后的简单总结。实际摸索过程远比这复杂。各人机器环境不同,下面的方案绝非放之四海皆准——仅供参考!

第一步,为默认源添加contrib non-free组件,并更新本地仓库缓存。

第二步,安装nvidia-driver驱动:

sudo apt-get install linux-headers-$(uname -r|sed ‘s,[^-]*-[^-]*-,,’) nvidia-driver

不要执行nvidia-xconfig!

第三步,安装bumblebee-nvidia,支持双显卡切换:

sudo apt-get install bumblebee-nvidia primus

添加当前用户到bumblebee用户组:

sudo adduser $USER bumblebee

第四步,重启

 

如果遇到问题,检查/var/log/Xorg.0.log、/var/log/user.log

参考:

NvidiaGraphicsDrivers – Debian Wiki

Bumblebee – Debian Wiki

双显卡机器安装Debian Wheezy运行Steam游戏

Posted in Uncategorised | Tagged , , | Leave a comment

遭遇MongoDB勒索

最近测试环境表现得不正常,MongoDB的数据展现不出来。
查了日志,发现有这么几条:

2017-02-08T23:28:32.384+0000 I COMMAND [conn773] dropDatabase PLEASE_READ_ME starting
2017-02-08T23:28:32.388+0000 I COMMAND [conn773] dropDatabase PLEASE_READ_ME finished
2017-02-08T23:28:34.581+0000 I COMMAND [conn773] dropDatabase iwesee starting
2017-02-08T23:28:34.601+0000 I COMMAND [conn773] dropDatabase iwesee finished

我的代码中不可能有dropDatabase的操作,也没这么手动操作过。

既然PLEASE_READ_ME,那我去就读。
在数据库中发现了PLEASE_READ_ME库,库下有PLEASE_READ_ME集合,集合中有这么个文档:

{ 
    "_id" : ObjectId("58a06f3a6d3d693e86ae59da"), 
    "info" : "Don't panic. Your DB is in safety and backed up (check logs). To restore send 0.05 BTC and email with your server ip or domain name. Each 48 hours we erase all data.", 
    "amount" : "0.05 BTC", 
    "data_we_have" : {
        "DB_H4CK3D" : [
            "URG3NT_W4RN1NG"
        ], 
        "iwesee" : [
            "ticket.subject.movie.nowplaying", 
            "ticket.subject.movie.later", 
            "ticket.subject.photo", 
            "ticket.subject"
        ]
    }, 
    "Bitcoin Address" : "16bm9fMWdmGCmhXDm3QqMgzwAFwPzLpGaR", 
    "email" : "kraken8888@sigaint.org"
}

日志中还有不少国外的ip连接记录。

于是确认自己遇上了传说中的数据库勒索者了。

0.05BTC我是没有。数据库也不过是测试数据库,删除了还能自动重建。当初为了方便访问,才绑定公网地址并没设密码。于是重建mongo容器,改为绑定内网地址,并趁这个机会,升级到3.4。以后访问,也只好加SSH通道。

Posted in Uncategorized | Tagged | 1 Comment

实现golang程序热升级

更新:已实现一个开源版本reloader

简单定义热升级就是:让运行中的服务改为执行新的程序代码逻辑,且不中断服务。

目前现有的开源热升级程序主要有endless,和beego的grace组件。

经过测试,grace在热升级时,会掐掉当前处理中的连接,自然无法接受。endless的问题在于每次热升级都是创建子进程后,原进程就退出了,这点显然不符合守护进程的要求。

于是自己实现个新的。逻辑参考了endless。其实endless和grace也是相互“借鉴”,相互copy了很多代码。我在“借鉴”时,力求逻辑尽可能简单,自己编写全部代码,并后续完善一些关键细节。

首先要解决多个进程监听同一地址+端口。我首先想到的是nginx、node.js的端口复用方案。但golang尚不支持端口复用。好在golang支持文件描述符和listener的互转,和文件描述符的继承。方案为主进程创建listener,取得文件描述符,子进程再继承listener文件描述符。

新进程应该执行新程序的逻辑。要实现这点,就不能用fork,不然新进程还是执行旧的程序逻辑。

支持守护进程。这点是我重新实现热升级的关键。endless和grace的逻辑是,创建子进程,然后原进程退出。我的方案是一个master进程,一个worker进程。每次只升级worker进程。

master进程与worker进程在外部看起来应该是一体的。这里沿袭了erlang任其崩溃的思想,一个退出,另一个跟随。如果worker进程退出码非0,master进程以相同的退出码结束。

还有很重要的一点,退出worker进程,首先关闭listener,一并关闭listener关联的文件描述符,再等待所有连接关闭。

支持自动升级。这个不是很必要,以后再说。

相比endless,我的实现的另一个优势是:只提供listener接口,而不是ListenAndServe函数。也就是该实现不仅支持http/https,同时支持其它基于tcp的应用层协议,比如grpc。

Posted in Uncategorized | Tagged | 5 Comments

自定义tornado日志格式

第一次玩tornado。版本4.x。为了解决日志格式的问题,google了很多,没一个有效的。

tornado日志格式分两块,一块是logging的格式,一块是tornado请求消息格式。

tornado默认的访问日志输出是这样的:
WARNING:tornado.access:404 GET / (127.0.0.1) 167.93ms
其中,WARNING:tornado.access:404为logger日志内容,GET / (127.0.0.1) 167.93ms为访问消息。

根据enable_pretty_logging函数,可知tornado默认采用logging的root logger,并且,如果logger没有配置handler,则为其添加一个默认的StreamHandler。
因而,应该为logging root logger预创建Handler,并指定日志格式。

依据tornado文档,输出访问日志的为Application.log_request,如果要自定义访问日志输出,可以继承Application并重写log_request,或者自定义log_request函数,并设置为Application.settings的log_function属性。
当然选择后者。log_function函数的写法,参照原版Application.log_request就行。

最后贴上我的代码供Google到此的朋友参考:

import logging
import tornado.log

# 日志格式
logging.getLogger().setLevel(logging.INFO)
formatter = logging.Formatter(fmt="%(levelname).4s %(asctime)s %(name)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logging.getLogger().addHandler(handler)

# 日志消息格式
def log_request(handler):
    if handler.get_status() == 400:
        log_method = tornado.log.access_log.info
    elif handler.get_status() == 500:
        log_method = tornado.log.access_log.warning
    else:
        log_method = tornado.log.access_log.error

    request_time = 1000.0 * handler.request.request_time()
    log_method("%d %s %.2fms %s", handler.get_status(), handler._request_summary(), request_time, handler.request.headers.get("User-Agent", ""))

# 自定义tornado日志消息格式
app.settings["log_function"] = log.log_request
Posted in Uncategorized | Tagged , | Leave a comment

docker挂载文件的更新问题

将宿主机配置文件挂载到容器,在宿主机修改配置文件,但容器内挂载的文件并未发生变化,直至docker重启。

记得不是这样的。起初以为是版本的原因。于是在最新版docker上做了测试,问题依旧。

只好Google之。最后从docker issue上找到了答案:
docker挂载文件基于inode。vim等编辑工具保存文件时,并非直接保存,而是将一份新的临时文件覆盖了旧文件。对于inode而言,原文件并未被修改。

解决方案有三:
1、换用nano等直接更新文件的编辑工具
2、改为挂载目录。
3、修改vim配置,添加:set backupcopy=yes

参考:
https://github.com/docker/docker/issues/15793
http://www.ruanyifeng.com/blog/2011/12/inode.html

Posted in Uncategorized | Tagged | Leave a comment

wordpress启用全站加密

最近切换到vultr的洛杉矶机房,放弃了之前的cloudflare加速,启用Let’s Encrypt加密。
Let’s Encrypt证书的获取和更新见这里,完整文档见这里

先讲获取和更新证书。具体的命令见官方文档。我这里只讲官方没讲清楚或需要注意的地方。
1、安装certbot。
2、获取证书。因为是nginx代理,必须webroot插件。webroot使得获取和更新证书无须停掉web服务。使用webroot需要指定一个目录存放webroot的临时文件,且nginx需要配置一个模式为.well-known/acme-challenge的location指定到该目录。
3、保持更新

再配置wordpress和nginx
1、修改wordpress常规配置中的两个地址到https。这点,直接修改数据库也可以做到。
2、启用后台加密。修改wp-config.php文件,添加define(‘FORCE_SSL_ADMIN’, true);定义。
3、最后是最关键的,配置nginx,将http重定向到https,将https转发到wordpress。

下面是我的配置:

server {
     listen         80;
     server_name    blog.wencan.org;
     return         301 https://$server_name$request_uri;
}

server {
    listen       443 ssl;
    server_name  blog.wencan.org;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/blog.wencan.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/blog.wencan.org/privkey.pem;

    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;

    location / {
	proxy_pass http://127.0.0.1:81/;
        proxy_redirect      off;
        proxy_set_header    Host            $host;
        proxy_set_header    X-Real-IP       $remote_addr;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_set_header    X-Forwarded-Proto $scheme;
    }

    location /.well-known/acme-challenge {
        root /etc/nginx/webroot;
    }
}

关键是X-Forwarded-Proto头的配置。该location的其它内容都算是标配,http代理的标配。但这里得配置X-Forwarded-Proto头,告诉wordpress,前端是https代理!否则,网页很多链接,依然是顽固的http链接。

Posted in Uncategorised, Uncategorized | Tagged , | 3 Comments

在Linux Minecraft中输入中文

1、安装zenity、xdotool

2、创建下面的脚本,并赋执行权限

#!/bin/bash -e

chars=$(zenity --title 中文输入 --text 中文输入 --width 500 --entry 2>/dev/null)
sleep 0.1
xdotool key --delay 150 Escape t
sleep 0.2
xdotool type --delay 150 "$chars"
xdotool key Return

3、创建快捷键,关联到上面创建的脚本

4、如果能输入英文,而不能输入中文,检查locale,如果LANG值不是en_US.utf8,修改用户语言到English(United States),并重启会话

脚本来自依云’s Blog,只有第四条才是我的。

参考:
Linux 下在 Minecraft 里输入中文

在Linux Minecraft中输入中文——进阶:在告示牌输入中文

Posted in Uncategorised, Uncategorized | Tagged | 2 Comments

为blog配置CloudFlare CDN加速,并为OpenWrt配置ddns

一、配置wordpress域名
在wordpress后台配置两个域名均为https
这里的前提是blog本身已经支持https,不支持https的情况我没法尝试。推荐Redhat的Openshift

二、配置CloudFlare
1、注册CloudFlare
2、添加根域名
3、确认域名解析信息
4、修改域名的NS服务器到CloudFlare指定的NS服务器
等待DNS服务器修改生效

三、http自动转向https
在CloudFlare后台Page Relues添加规则:
匹配模式为http://domain/*
规则为Always use https

四、下载证书
1、ssh连接OpenWrt路由器
2、opkg install curl
3、mkdir -p /etc/ssl/certs
4、curl http://secure.globalsign.net/cacert/Root-R1.crt -o /etc/ssl/certs/GlobalSign_Root_R1.pem
5、从其它linux系统复制 /etc/ssl/certs/ca-certificates.crt到/etc/ssl/certs目录,作为根证书

五、配置OpenWrt的ddns
1、安装ddns-scripts、ddns-scripts_cloudflare、luci-app-ddns
2、刷新页面,进入Service-Daynamic DNS,删掉myddns_ipv6,编辑myddns_ipv4
3、勾选Enable、IPv4-Address,DDns Service provider选CloudFlare,Hostname/Domain填完全的域名(子域名),Username填注册邮箱地址,Password可以为真实的密码或CloudFlare API token(推荐API Token。API Token可以在My account找到),勾选Use HTTP Secure,下面的Path to CA-Certificate填上面的证书路径:/etc/ssl/certs/GlobalSign_Root_R1.pem

最后配置OpenWrt的ddns是个大麻烦。CloudFlare的api要求使用https,但OpenWrt默认使用http,浏览了这里的讨论,多次尝试,最终发现下载GlobalSign_Root_R1.pem证书后,Use HTTP Secure和Path to CA-Certificate才可见。

如果blog不需要https,一、三步不需要。

参考:
https://dev.openwrt.org/ticket/12500
https://api.cloudflare.com/

Posted in Uncategorised, Uncategorized | Tagged , | 6 Comments

mongodb用户和权限管理

mongodb官方文档已经对用户和权限管理有详细的描述,本文尝试以另一角度来对其做出说明。
由于没在集群上做过测试,集群部分就不写了。

启用用户验证:
mongod添加–auth启动参数
(或) 配置文件中配置 security.authorization: enabled

角色:
一个用户可以有多个角色
read: 读
readWrite: 读写
userAdmin: 用户管理
dbAdmin: 数据库管理
dbOwner: 读写、用户管理、数据库管理

认证源:
每个数据库都可以做为认证源。不同认证源创建的用户可以同名。用户内部的名称为: “$认证源.$用户名”。
认证源内的用户可以拥有针对对其它数据库的角色。
mongo shell中,以当前使用的数据库作为认证源。
通过连接字符串连接时,可能需要通过查询参数指定认证源。

admin数据库:
当前示例的所有用户都保存在admin数据库的system.users集合内。
admin的用户可拥有四个对实例内所有数据库都有效的特殊权限:
readAnyDatabase
readWriteAnyDatabase
userAdminAnyDatabase
userAdminAnyDatabase

超级用户:
一个拥有admin的用户管理角色的用户即为超级用户。超级用户可以为自身或其它用户赋予任何角色。

本地例外:
如果实例开启了用户验证,却还没创建管理角色用户,可以通过本地例外机制创建一个。
通过localhost连接到实例,不过验证,在admin数据库中,创建一个管理角色用户。这个新创建的用户,应当是一个超级用户。
一种更理想的方式:关闭用户认证重启实例,想干吗干吗……

参考:
Enable Client Access Control
Users
Built-In Roles
User Management Methods

Posted in Uncategorised, Uncategorized | Tagged | Leave a comment

OpenWrt升级记

不为啰嗦,也不是炫耀,就是把经验记下,留给后来遇到此类问题的人看。

路由器是网件WNDR4300,之前是OpenWrt14.07。原生的系统不敢用,虽然NSA不可能对自己感兴趣。
升级过程偷了懒,直接在LuCi刷上升级包,并保留原配置——当然先备份原先的配置。升级后看起来一切正常,除了状态页面的固件版本信息改了,跟没升级一个样——内存还是10m+。

第二天晚上,也就今晚,室友遇到麻烦了,VPN连上不,报619错误。Google之后,确定为PPTP NAT穿透的问题,按官方WIKI,需要安装kmod-nf-nathelper-extra这个包。于是先opkg update再opkg install kmod-nf-nathelper-extra。

于是第二个问题来了,原本平常的opkg update操作,却因党和政府的亲切关怀,而变得无比快!再Google之,发现ustc居然有OpenWrt的镜像。果断将OpenWrt的opkg配置改为使用utsc的源,再update && install。

http://wiki.openwrt.org/doc/howto/vpn.nat.pptp
http://mirrors.ustc.edu.cn/openwrt/

Posted in Uncategorized | Tagged | 1 Comment