2017年8月4日星期五

记录一次快速硬盘安装Debian的过程

使用Debian  testing版本,在一次升级后dbus服务起不来了,导致一系列的服务启不来,救援模式下可以操作,但不想花时间去研究修复系统,再加上之前硬盘分区不合理,根分区太小,干脆重装了。

在此记录安装过程

从Debian网站下载网络安装用的ISO,100多M,解压到U盘根目录,使用现有的GRUB2 加载解压出来的vmlinuz和initrd.gz
顺利启动安装进程,然后提示找不到安装光盘,此时按 ALT+F2 进入shell,  把U盘挂载到/cdrom目录,然后ALT+F1回到安装界面按照提示就可以继续安装了。

可能是我没有添加启动参数,安装过程中软件安装部分无法选择,安装完的系统只是base system.

进入新系统后修改/etc/apt/source.lst添加软件源,使用apt-get install task-lxde-desktop, 桌面又回来了。

2015年11月6日星期五

通过openvpn使用搬瓦工ipv6

买了个搬瓦工的便宜vps,发现可以分配3个ipv6地址,于是折腾ipv6 in ipv4 tunnel,终于折腾成功了。记录下过程。

搬瓦工的ipv6是/64的地址段,但是只让你用3个地址,这3个地址我们可以自定义。
假如分配到的ipv6前缀是 2001:db8:1:123, 我们自定义成如下地址
2001:db8:1:123::1
2001:db8:1:123::a0:1
2001:db8:1:123::a0:1000
第一个地址用在venet0上,第二个用在tun0上,第三个给客户端用。 之所用a0:1,a0:1000 是因为给openvpn 一个 /64 的地址,openvpn自动给自己用:1,给第一个客户端用:1000,这样就不用手动配ip地址了。
分配完成后重户vps,进入系统会发现三个ipv6地址全在venet0,我们删除两个, 用以下命令
ip addr del 2001:db8:1:123::a0:1 dev venet0
ip addr del 2001:db8:1:123::a0:1000 dev venet0
最好是把以上命令放入/etc/rc.local中,系统启动时自动执行。
修改openvpn配置文件,增加ipv6配置
server-ipv6 2001:db8:1:123::a0:0/64
push "route-ipv6 ::/0"
打开ipv6转发设置
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.forwarding=1
把以上写入/etc/sysctl.conf,用sysctl -p生效,或者用如下命令临时生效,重启后失效
sysctl -w net.ipv6.conf.all.forwarding=1
sysctl -w net.ipv6.conf.default.forwarding=1
防火墙允许转发
ip6tables -P FORWARD ACCEPT
或者根据条件允许转发
ip6tables -P FORWARD DROP
ip6tables -A FORWARD -p tcp --dport 80 -j ACCEPT
ip6tabels -A FORWARD -p tcp --dport 443 -j ACCEPT
重启openvpn服务端,客户端重新连接, 在客户端机器上ping 地址2001:db8:1:123::1,2001:db8:1:123::a0:1, ipv6.google.com
如果都能通,配置就完成了。

配置文件

以下是我的server端配置文件
server 10.0.8.0 255.255.255.0
topology subnet
server-ipv6 2001:db8:1:123::a0:0/64
port 11948
proto tcp
dev tun
push "redirect-gateway def1 local"
push "topology subnet"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 4.2.2.2"
push "ping 5"
push "ping-restart 30"
push "route-ipv6 ::/0"
push "route 23.xxx.xxx.xxx 255.255.255.255 net_gateway"
keepalive  5 30
duplicate-cn
persist-key
persist-tun
group nogroup
user nobody
tls-auth ta.key
ca ca.crt
cert server.crt
key server.key
dh dh.key
以下是客户端配置文件
client 
proto tcp
dev tun
verb 3
remote 127.0.0.1 11948 tcp
http-proxy 127.0.0.1 8080
http-proxy-retry 10
http-proxy-timeout 10   
keepalive 10 60
route 192.168.1.0 255.255.255.0 net_gateway
script-security 2
#route-up d:/add_route.bat
#route-pre-down d:/del_route.bat
ca ca.crt
cert client.crt
key client.key
tls-auth ta.key

参考链接

2015年3月28日星期六

让你的web server支持http/2.0

http/2.0 是下一代的http协议(查看wikipedia),它 比http/1.1具有更高的效率,目前还没有正式发布,还处在修改阶段,新最的标准是draft-17h2-17.
目前chromefirefox都已支持http/2.0了,我们可以在自己的网站上部署http/2.0来尝新。
我们可以使用这个C语言的http/2.0的库nghttp2, 安装方法:
git clone https://github.com/tatsuhiro-t/nghttp2
cd nghttp2
autoreconf -ivf
./configure
make
sudo make install
安装成功后,有如下组件:
libnghttp2-xx.so 解析http/2.0的协议的库文件
nghttp 一个http/2.0的客户端程序,类似于wget
nghttpx 一个http/2.0的代理程序, 类似于squid
nghttpd 一个http/2.0的web server程序, 类似于nginx
如果你的web server只有静态文件, 使用nghttpd就够了
nghttpd -d /path/to/docroot 443 server.key server.crt
如果不用ssl
nghttpd -d /path/to/docroot 80 --no-tls
如果要支持php等动态内容,你可以使用nghttpx作为前端,后端使用nginx或者apache, 像这样
nghttpx -f '0.0.0.0,443' -b 127.0.0.1,81 --cert server.crt --key server.key
nghttpx监听443端口,接收http/2.0请求,然后转发到127.0.0.1:81端口,让apache运行在此81端口处理实际的请求。
nghttpx黙认是启用ssl的,如果你的网站没有部署ssl,也可以使用不带sslhttp/2.0,命令如下
nghttpx -f '0.0.0.0,80' -b 127.0.0.1,81 --frontend-notls
当然了,nghttpx/nghttpd也支持http/1.1http/1.0协议,完全不用担心不支持http/2.0的浏览器。
如果你安装了spdylay库, 在启用ssl时,nghttpd/nghttpx也支持spdy/3.1协议。
更多关于nghttp2的信息点击这里.

2014年11月27日星期四

亚马逊aws配置多个公网ip的问题

公司的服务器切换到亚马逊aws服务器, 我们的服务需两个公网ip, 在aws上申请到了两个公网ip, 并且配置成功。
aws服务器使用的是内网ip通过NAT转换成公网ip的方式.
映射关系如下:
$public_ip1 ---> $private_ip1 ----> eth0
$public_ip2 ---> $private_ip2 ----> eth1
但是使用过程发现只有一个公网可以通。
当黙认网关设置在eth0上时,$public_ip1可以通, $public_ip2不通;当黙认网关设置在eth1上时$public_ip2可以通,$public_ip1不通。
于是我做了如下操作:
把黙认网关设置在eth0上, 在公网ip为123.123.123.123的机器上ping $public_ip2,然后在服务器上使用ip route show cache查看路由表缓存,发现服务器到123.123.123.123的路由走的是eth0, 也就是说$public_ip2接收到的数据包,返回的时候走的是eth0,源ip会被NAT成$public_ip1, 所以会$public_ip2不通。
问题的原因已经明白了,现在要做的就是怎样让从eth1进入的数据包从eth1返回,eth0接收到的数据包从eth0返回。
这里我使用Linux的iproute2功能,让eth0eth1查找不同的路由表
先执行如下命令,添加两条路由表别名
echo 200 t_eth0 >> /etc/iproute2/rt_tables
echo 201 t_eth1 >> /etc/iproute2/rt_tables
然后在路由表中添加路由规则
ip route add default via $gw_eth0 dev eth0 table t_eth0
ip route add default via $gw_eth1 dev eth1 table t_eth1
再添加路由查找规则
ip rule add from $private_ip1 table t_eth0
ip rule add from $private_ip2 table t_eth1
以上规则的意思是,当源ip为$private_ip1时,查路由表t_eth0,在表t_eth0中,黙认走eth0; 当源ip为$private_ip2时,查路由表t_eth1,表t_eth1中,黙认走eth1
这样设置之后,不管黙认网关设置在哪个网卡上,两个公网ip都可以通了。

2014年9月29日星期一

反向代理twitter.com的nginx配置文件

折腾nginx反向代理,终于配置成功了twitter.com的反向代理,可以登陆成功。
首先,需要安装 HttpSubsModule 模块,参见 http://wiki.nginx.org/HttpSubsModule
在http部分加入如下指令,使HttpSubsModule替换javascript中域名,否则登陆时无法输码
subs_filter_types  application/x-javascript application/javascript;

反代twitter.com的配置

server {
    server_name t.example.org;

    #proxy_cache cache1;

    listen 443 ssl spdy;

    add_header Strict-Transport-Security max-age=3153600;
    #add_header X-Frame-Options DENY;

    # 证书
    ssl_certificate      /home/user/a.example.org.crt;
    ssl_certificate_key  /home/user/a.example.org.key;

    #root t.example.org;

    # 禁止搜索引擎
    if ($http_user_agent ~ (google|bot|baidu) ){
        return 403;
    }

    location / {
        proxy_set_header Accept-Encoding "";
        proxy_set_header Accept-Langauge "zh-CN";
        proxy_set_header Host $proxy_host;

        proxy_pass https://twitter.com/;

        # cookie domain replace
        proxy_cookie_domain twitter.com t.example.org;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # 域名替换
        subs_filter twitter.com t.example.org;
        subs_filter abs.twimg.com abs.example.org;
        #subs_filter t.co co.example.org;
    }

}

反代abs.twimg.com的配置

server {
    server_name abs.example.org;

    #proxy_cache cache1;

    listen 443 ssl spdy;

    add_header Strict-Transport-Security max-age=3153600;
    add_header X-Frame-Options DENY;

    # 证书
    ssl_certificate      /home/user/a.example.org.crt;
    ssl_certificate_key  /home/user/a.example.org.key;

    #root abs.example.org;

    # 禁止搜索引擎
    if ($http_user_agent ~ (google|bot|baidu) ){
        return 403;
    }

    location / {
        proxy_set_header Accept-Encoding "";
        proxy_set_header Accept-Langauge "zh-CN";
        proxy_set_header Host $proxy_host;

        proxy_pass https://abs.twimg.com/;

        # cookie domain replace
        proxy_cookie_domain twimg.com abs.example.org;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # 域名替换
        subs_filter twitter.com t.example.org;
        subs_filter abs.twimg.com abs.example.org;
        #subs_filter t.co co.example.org;
    }
}
我是使用子域名反代twitter域名的方式, 理论上可以使用子目录反代域名的方式,但是这种配置会比较麻烦,很是考验耐心,我成功配置过用子目录反代google。
abs.twimg.com 我这里可以直接访问,但是有一个js文件控制着登陆框的密码输入,所以反代后替换掉域名,就可以输入密码了。
pbs.twimg.com是图片的域名,我这里可以直接访问,就不用反代了。
2014-09-29 18:24 更新:
删除了t.co配置部分,因为如果替换域名t.co, 会连带替换到脚本中的一些其它东西,脚本会执行出错。

2014年9月10日星期三

利用cx_freeze在没有Python的Windows上运行Python源代码

在没有安装Python运行环境的Windows机器上运行python程序,大家的通常做法是使用cx_freeze/pyinstaller等打包成exe文件,我也是一直这样做。但是有一个问题,程序做很小的改动的时候,都需要重新打包,然后再拷备过去等一系列复杂的操作。
我发现goagent项目就是提供的源码,在windows上是用一个python27.exe的程序解释源程序。研究了一番,发现goagent是使用py2exe把依赖的库打包成一个zip文件,然后再做一个python27.exe的程序, 由python27.exe来执行,并且有一个单独的项目,名为pybuild,项目见这里
我使用pybuild的脚本来处理我的程序,希望做成跟goagent一样的效果,结果发现pybuild/py2exe根本搞不定pygtk。
我只有另想办法了,cx_freeze打包的时候可以生成一个单独的压缩包,里面包含依赖的库。看来cx_freeze可以做成goagent的效果。
我直接使用pybuid里面的python27.py来生成python27.exe, 然后再写一个py文件(collect_libs.py)把程序里用到的库全部import一遍。然后利用cx_freeze把python27.py和collect_libs.py打包,完成后删除生成的collect_libs.exe。包含python27.exe的目录就是程序的运行环境, 可以直接使用python27.exe执行python程序。
使用的setup脚本如下
from cx_Freeze import setup, Executable

# Dependencies are automatically detected, but it might need
# fine tuning.
buildOptions = dict(
        packages = [], excludes = [],
        include_msvcr = True,
        include_in_shared_zip = True,
        )

executables = [
    Executable('python27.py', 'Console'),
    Executable('collect_libs.py', "Console")
]

setup(name='python27',
      version = '1.0',
      description = 'the python shell',
      options = dict(build_exe = buildOptions),
      executables = executables)
测试了一下,效果还不错。与pybuild/py2exe相比, cx_freeze把dll,pyd放在目录里面,zip文件里面是pyc文件,而pybuild是把dll, pyd, py文件全放在压缩包里。
需要注意的是,如果cx_freeze处理使用了gevent的程序,需要对cx_freeze本身做一些修改, 修改freezer.py文件中的EXTENSION_LOADER_SOURCE = 内容中的 import os, imp, sys为如下形式,详情参考这里
os = __import__("os")
imp = __import__("imp")
sys = __import__("sys")
另外,cx_freeze不能处理egg文件,需要手动拷备egg文件到目标目录下,在程序的最开始加入如下内容,才能正确的import egg文件
import sys
import glob
for egg in glob.glob("*.egg"):
    sys.path.append(egg)

2014年8月28日星期四

Linux 下SQLITE数据库无法在NFS/CIFS之上运行的解决办法

我在debain下mount了samba(CIFS)共享, 然后运行mindlna,让minidlna stream samba上的视频和音乐, 无奈minidlan拒绝工作。我启用debug模式,发现在minidlna启动时,sqlite数据库建表失败。于时我修改数据库的存放路径到本地的ext4文件系统上,minidlna工作良好。
由此推断可能是CIFS的问题, 于是我使用 sqlite /mnt/media/test.db测试,/mnt/media是samba的挂载点。我输入如下的SQL语句测试:
create table t1 (a int, b int);
直接报如下错误:
table is locked
我使用google搜索了一圈,发现很多人有此问题, 但都没有解决方案,最终在一个英文论坛上发现有人提到添加nolock参数, 但是提问的人没有回复效果。
我于是添加nolock参数、重新挂载samba来测试一下效果:
umount /mnt/media
mount -t cifs -o user=myuser,password=mypass,nolock //172.16.1.5/share /mnt/media
然后,再次使用sqlite /mnt/media/test.db测试,create tableinsertdeleteupdate 等SQL操作都可以成功,不会有任何错误了。把minidlna的数据库路径修改到samba上也没有问题了。
所以nolock参数可以解决此问题,于是修改/etc/fstab添加nolock让系统启动时自动使用nolock参数挂载:
//172.16.1.6/share  /mnt/media  cifs    defaults,user=myuser,password=mypass,nolock 0 0