Fork me on GitHub

如何封杀尝试Raspberry Pi SSH密码的来源IP 2013-03-08

Raspberry Pi整天开着,如果用缺省SSH端口对外开放,就会经常遇到扫描SSH密码的肉鸡。虽然密码不是很简单,但还是感觉很不安全的。

系统的ssh登录日志文件在:/var/log/auth.log,登录失败时会记录以下格式的日志:

Mar  7 10:31:51 raspberrypi sshd[24510]: Failed password for root from 221.8.19.129 port 4066 ssh2
Mar  7 10:31:55 raspberrypi sshd[24514]: Failed password for root from 221.8.19.129 port 4079 ssh2
Mar  7 10:31:56 raspberrypi sshd[24518]: Failed password for sshd from 221.8.19.129 port 4080 ssh2
Mar  7 10:32:26 raspberrypi sshd[24522]: Failed password for sshd from 221.8.19.129 port 4149 ssh2

用最简单的Shell脚本来解决这个问题:

guard.sh

#!/bin/bash

last_ip=""
tail -f /var/log/auth | while read LINE; do
{
    if [[ "${LINE}" =~ "Failed" ]]; then            
        ip="$(echo ${LINE} | awk '{print $(NF-3)}')"
        if [[ "$last_ip" == "$ip" ]]; then
             echo "block $ip"
             #curl -s --data-ascii "uuid=<my iphone's uuid>" --data "body=${LINE}" http://raspberrypi/pushme                 
             iptables -A INPUT -s "$ip" -j DROP
        fi
        last_ip=$ip
        echo $LINE
    fi
}
done

Raspberry Pi做BT下载机+高清播放器 2013-03-06

介绍

首先高清播放器功能只是Raspberry Pi的一个小功能,如果你只需要高清播放功能又不想折腾,那还是买个山寨的的更简单。。。

Raspberry Pi的图形处理器规格:Broadcom VideoCore IV, OpenGL ES 2.0, 1080p 30 h.264/MPEG-4 AVC 高清解码器,内存和CPU共享(可设置成256M),性能还是很强劲的。HDMI支持640x350和1920×1200(1080P)的分辨率。安装了XBMC,基本上可以实现包括Airplay在内的Apple TV上的大部分功能,但价格只有其一半不到,可以播放下载的视频或观看在线视频,如一搜,优酷,搜狐视频,奇艺等。

外设

除了Pi单片机外,你还需要以下外设附件:

  1. 5V-1A左右的电源,可以用iPhone或iPad的充电电源,或手机的充电器,电流最少要800毫安
  2. micro USB线一根,和Kindle以及大多数android手机充电USB线一样
  3. HDMI线一根,接电视机
  4. SD卡一张,最少2G

Raspbmc

Raspbmc 是专为在Raspberry Pi上运行XBMC的定制Linux。最小化的安装,减少了不必要的软件和资源占用,简化了安装和配置,没有Linux知识也可以上手。这个版本的维护者是一个19岁的小朋友Sam Nazarko。有时间折腾的同学可以自己编译XMBC安装。

特点:

  1. 免费,开源
  2. 支持多语言
  3. 支持1080P回放
  4. 支持直接播放NFS,SMB,FTP,HTTP或USB硬盘的有视频文件,支持大多数格式
  5. 支持AirPlay或AirTune功能,可以把iPhone/iPad上的视频或音乐通过Pi投放到电视上,这点和Apple TV功能一样
  6. 支持GPIO
  7. 基于Debian,可以从Debian的软件源安装其它软件
  8. 支持1080P DTS软解,这个不少播放器是不支持的,需要额外License
  9. 内置了以下服务:
    1. Samba
    2. TVHeadend Server
    3. FTP Server
    4. SSH Server

Java并发包中的同步队列SynchronousQueue实现原理 2013-03-05

介绍

Java 6的并发编程包中的SynchronousQueue是一个没有数据缓冲的BlockingQueue,生产者线程对其的插入操作put必须等待消费者的移除操作take,反过来也一样。

不像ArrayBlockingQueue或LinkedListBlockingQueue,SynchronousQueue内部并没有数据缓存空间,你不能调用peek()方法来看队列中是否有数据元素,因为数据元素只有当你试着取走的时候才可能存在,不取走而只想偷窥一下是不行的,当然遍历这个队列的操作也是不允许的。队列头元素是第一个排队要插入数据的线程,而不是要交换的数据。数据是在配对的生产者和消费者线程之间直接传递的,并不会将数据缓冲数据到队列中。可以这样来理解:生产者和消费者互相等待对方,握手,然后一起离开。

SynchronousQueue的一个使用场景是在线程池里。Executors.newCachedThreadPool()就使用了SynchronousQueue,这个线程池根据需要(新任务到来时)创建新的线程,如果有空闲线程则会重复使用,线程空闲了60秒后会被回收。

实现原理

同步队列的实现方法有许多:

阻塞算法实现

阻塞算法实现通常在内部采用一个锁来保证多个线程中的put()和take()方法是串行执行的。采用锁的开销是比较大的,还会存在一种情况是线程A持有线程B需要的锁,B必须一直等待A释放锁,即使A可能一段时间内因为B的优先级比较高而得不到时间片运行。所以在高性能的应用中我们常常希望规避锁的使用。

public class NativeSynchronousQueue<E> {
    boolean putting = false;
    E item = null;

    public synchronized E take() throws InterruptedException {
        while (item == null)
            wait();
        E e = item;
        item = null;
        notifyAll();
        return e;
    }

    public synchronized void put(E e) throws InterruptedException {
        if (e==null) return;
        while (putting)
            wait();
        putting = true;
        item = e;
        notifyAll();
        while (item!=null)
            wait();
        putting = false;
        notifyAll();
    }
}

OpenVPN使用多个端口 2013-03-02

Openvpn本身不能设置多个端口,使用iptables可以解决这个问题 (假设openvpn本来56788端口):

for port in {56780..56787}
do 
    iptables -t nat -A PREROUTING -p tcp -d <your_external_ip> --dport $port -j REDIRECT --to-port 56788
done

在Ubuntu上配置L2TP,PPTP和OpenVPN服务 2013-03-01

Overview

MacOS, Windows, iOS都内置支持PPTP,L2TP;OpenVPN需要安装客户端,手机上一般不支持。

先打开内核的IP转发,修改 /etc/sysctl.conf

net.ipv4.ip_forward=1

执行下面命令以生效

sudo sysctl -p

PPTP

安装pptpd

apt-get install pptpd

Java的资源管理 2013-03-01

Overview

Java程序中的常见的资源有:文件,Socket,数据库连接。在使用这些资源时候要分外小心,因为操作系统可同时操作的资源是有限的,比如默认情况下系统允许同时打开的文件数为1024个,Mysql服务器默认允许的最大连接数是100,所以操作这些资源时候要注意即使在遇到错误时也要让系统能正确回收资源。如果发生错误时候,打开的文件描述符没关闭或数据库连接没关闭,积累到一定程度后,应用将会变得不可用,只能重启。

try-catch-finally

Java提供了try-catch-finally来保证程序遇到异常时总是有机会可以处理资源的关闭 -- 调用资源对象的close()方法。但经验不足的Java程序员还是会错误的管理资源,而造成资源的泄露,静态代码分析工具,如FindBugs可以帮助发现此类问题。

首先我们来看一段文件操作代码:

private void copy(String from, String to) throws IOException {
    FileInputStream in = null;  
    FileOutputStream out = null;  
    in = new FileInputStream(from);  
    out = new FileOutputStream(to);  
    int c;  
    while ((c = in.read()) != -1)
        out.write(c);  
    in.close();
    out.close();
}

在线广告系统架构变迁 2013-02-28

Overview

(未完)

广告按业务划分有以下几类:

  1. 展示广告(Banner广告)
  2. 搜索广告(关键词广告)

按计费模式有:

  1. CPT: 按有效广告展示天数计费,可定价或竞价;
  2. CPM: 按有效广告展现次数计费,可定价或竞价;
  3. CPC: 按有效点击次数计费;
  4. CPS: 按效果计费,如,按成交订单额,按流量带来的有效下载或安装次数计费;

广告系统按结构可划分为以下子系统:

Java程序的日志 2013-02-28

Overview

一个在生产环境里运行的程序如果没有日志是很让维护者提心吊胆的,有太多杂乱又无意义的日志也是令人伤神。程序出现问题时候,从日志里如果发现不了问题可能的原因是很令人受挫的。本文想讨论的是如何在Java程序里写好日志。大多数的Web服务器(如Apache,Nginx)都有access日志和error日志,分别记录在不同的文件内;我们使用的服务器操作系统Linux有Syslog日志, /var/log目录下也有很多基础应用和服务的日志文件;桌面Windows有事件查看器, Mac有Console应用可以查看和管理日志;这些成熟的系统及工具方法都值得我们学习并在自己的项目中应用。

一般来说日志分为两种:业务日志和异常日志。使用日志我们希望能达到以下目标:

  1. 对程序运行情况的记录和监控;
  2. 在必要时可详细了解程序内部的运行状态;
  3. 对系统性能的影响尽量小;

日志规范

程序框架应该提供统一的日志记录接口,日志格式也需要有一定的规范,方便利用日志工具来分析日志。 首先我们有必要了解一下Linux普遍使用的Syslog标准协议,协议规定日志中应包含产生日志的模块(Facility),严重性(Severity Level),时间,主机名或IP,进程名,进程ID和日志内容,根据模块和严重性可以配置相应的动作:是否需要记录,日志存储路径(文件或网络)。

下面是部分常见的Syslog模块类型:

模块ID 关键词 描述
0 kern 内核消息
1 user 用户级别消息
2 mail 邮件系统
3 daemon 系统后台守护程序
4 auth 安全/鉴权消息
5 syslog syslogd内部产生的日志消息

在Pi和Github上搭建自己的个人博客 2013-02-27

方法如下:

本站同时托管在家里的Raspberry PiGithub Pages上,并同步保持更新,海外用户会访问Github,国内用户则会访问Pi,不同线路解析域名hugozhu.myalert.info到不同的服务器是通过DnsPod的服务实现的,这么好的服务还是免费的,这里推荐一下。

因为Github Pages只能支持静态网页,你需要一个能生成静态网页的博客生成引擎。我使用的是gor , 也可以使用ruhohGoogle一下还有很多

静态页面博客的好处:

  1. 性能是最好的,很合适用Raspberry Pi来做服务器,节省资源;
  2. 文章可以用Markdown格式来编写,采用Github来做版本控制,我的Blog仓库在 http://github.com/hugozhu/blog ,数据安全很好,误删除也不担心了;
  3. 很容易找到托管环境,方便迁移;
  4. 用Gor在Pi上生成速度很快;再用Nginx提供Web服务,可以直接在Pi上写Blog;
  5. 大繁至简

Github设置

  1. 在你的仓库里增加一个your_github_id.github.com,比如我的github ID是hugozhu,相应的仓库名就是hugozhu.github.com,这个仓库也就是网站的根目录了,在这里放生成好的静态文件
  2. 如果你需要用自己的域名,而不是Github提供的,可以在根目录下增加一个CNAME文件,文件内容则是你的域名,在DnsPod上需要建一个CNAME记录,将你的域名指向your_github_id.github.com. 也就是github原来分配给你的,完成这个设置后,访问your_github_id.github.com会跳转到你的域名;
  3. 每次更新后,Github会在10分钟内生效。

使用Github合作开发项目 2013-02-27

本文大部分内容来自: https://help.github.com/categories/63/articles

Github上合作开发最好的方式是“Fork + Pull Request”。比如我最近需要一个静态Blog生成器,市面上有很多Ruby实现的,但我想要一个Go语言的实现,Github上找到了一个 https://github.com/wendal/gor ,测试了一下已有的功能基本能满足了,就用上了。

但实际使用过程中发现了一个问题,如果在URL中有中文,生成的URL如下没有做URL安全编码:

http://hugozhu.myalert.info/2013/02/27/在Pi和Github上搭建自己的个人博客.html

还有一种情况是如果URL中有空格,如:

http://hugozhu.myalert.info//2013//02/25/Java properties to enviorment variables.html

浏览器遇到这种URL时,会主动进行编码,但这里有两个问题:

  1. 遇到中文时,浏览器是用GBK还是UTF-8还是其它字符集编码后再发送给服务器呢?
  2. 遇到空格时,编码成+还是%20呢? 不同浏览器实现可能不一样,在不同操作系统上也可能不一样(可能和用户设置的缺省语言有关),这样有些用户可能会遭遇404错误了,实际上我在服务器的错误日志上的确看到这样的错误

日志: