Trade Off

supercalifragilisticexpialidocious

Optimize Shadowsocks NAT Rules

Few days ago, I upgraded my OpenWrt box to latest version, there is a new style(Bootstrap) interface and I like it very much(too long lived old world).

Also I found a shadowsocks special version for openwrt, it includs China main IP blocks, some requests within this IP range, you could bypass shadowsocks, and this IP blocks is from apnic, very precise but a little long for openwrt, 4000+lines.

I think the most counted IP block I would use it in the future very soon, so I can sort them desc.

iptables -t nat -xvnL SS_SPEC_WAN_AC | tail -n+12 | head -n -1 | sort -crnsk 1,1 | awk '{ print $NF }' > /etc/shadowsocks/ignore.list

tail -n+12 means display results from the first 12 row to the end, first 11 rows includes two lines heads, one line shadowsocks server IP, eight lines internal IP blocks;

head -n -1 means display results except last line(doesn’t work on MacOS), and last line is default shadowsocks redirect rule, so keep it at the same place.

sort -crnsk 1,1 means check first, reverse result, numerical value(converted from input string), stable sort, k 1,1 sort key (start a key at POS1, end it at POS2 (origin 1))

awk print $NF, print the last column, that’s very cool.

rewrite the results to ignore.list, and restart shadowsocks, it will use the sorted IP blocks, maybe fast than before 0.xx ms!

Mailing List in Postfix

Too simple to making a mailing list in postfix, just define a mailing list name and recipients in /etc/postfix/virtual, like this: dev-group dev1@company.com dev2@company.com dev3@company.com, after that, generate the virtual db by postmap /etc/postfix/virtual.

Don’t forget add virtual_alias_maps=hash:/etc/postfix/virtual in your main.cf file, and restart postfix finally.

I think I need study postfix systemally, just build a private smtp/imap server.

Be Careful Python Fdopen

I have got a bug when I print something to stdout, I got Bad file descriptor, it means my stdout is a bad descriptor, what?!

Core code like this: logger.StreamHandler(os.fdopen(sys.stdout.fileno(), 'w', 0)), I want to a unbuffered stdout, so I reopen it by fdopen, and reset the buffer size to 0, I still also did same thing to stderr, but that is no sense, because of stderr is unbuffered normally(but in Python3, it maybe line buffered, in MacOS).

If your stdout is reopened by fdopen, and its reference count hits zero, it will be collected by Python GC, also your stdout will be ate by GC, something wrong will happen after that.

So, be careful with fdopen for stdin, stderr, stdin:)

联通封了80和8080 but 443 Is Ok

地点:北京
ISP:中国联通
接入方式:光纤入户

换联通宽带几个月了,感觉良好,但觉得BT下载不够快,因为下的少,也没深究,而且多用迅雷离线下载,基本就是直连迅雷CDN的速度,都能跑满带宽。

OpenWrt多拨尝试过,没有效果,据说早就被封了,所以不再尝试。

前段时间打算把openwrt的管理界面移到WAN和LAN上,即在外面也能访问路由器,默认我就放到了WAN的80上,很可惜失败了,内部访问没问题,外面不行,当时也没多想,总觉得是iptables有问题,一看openwrt的规则,好可怕,嵌套了几层,不看了,改成了别的端口,比如9999,竟然内外都可以,因为后来很少从外面访问,所以这个需求基本是为需求,不管了。

最近把一个网站放到raspberry pi上,路由器做端口映射到内部的80,当时在内网里测试的没问题,还把https也一并做好了。碰巧在公司访问了一下,80不能访问,但443没问题。

今晚直接在PREROUTING的第一行加了log,从外部服务器请求80直接看不到,但443的没问题,而且PREROUTING是第一个被执行的,只能说80的请求就没到这里,可这都是公网对公网的访问了,难道这个请求被某个路由截获然后丢弃了?Google了一下发现几年前几大运营商的能提供公网IP的服务里80和8080端口被封了,说是不能随意搭建网站,想想也是啊,现在国内都得备案才行。

BUT PORT 443 IS OK…

聚石塔里面的坑

今天开始全面接触聚石塔,就是天猫的云平台,上面服务众多,全都能收费,第一次听说了API调用也是可以收费的。下面记录一些可能成为坑的东西,希望有人看到后可以小心躲避。

创建应用要先报备

说明书要按照模版写,模板有下载,看说明就能找到,其中里面有个架构图,这个要仔细画,基本思想(阿里思想)就是把你所有的业务系统都放到ECS上,如果在ECS外出现了一个你们自己的平台,他们就怀疑你用ECS做了一个代理来调用API,因为收费API只能是塔内调用,其他没有遇到特别的,时间大概是3天出结果。

创建应用

报备通过就可以创建应用了,创建成功后可以去买ECS和RDS等服务,别的服务暂时没用到,这两个服务都是绑定应用的,所以要先有应用。ECS的配置可选的比较少,我在北京,但机房目前只有杭州,所以你写了你的位置也没用,据说杭州那个机房是6线接入,出口质量和淘宝一样,但拿到ECS后ping了一下,31ms左右,第二天ping到了70ms左右,虽然ping不代表什么,但总感觉怪怪的。。。价格和阿里云的ECS相比有些贵。

ECS

管理终端有个密码,要改的话记得改完重启机器,否则不生效,而且重启后自己再用管理终端连接一下看看是不是生效了。

他们把10和172.16网段都用了,自己要用内网的话可以考虑多租几个ECS实例,但想玩LXC的话,可以考虑用192.168网段。

DNS不要换别的,就用ECS配置好的,据说改了影响内部访问和RDS通信,我改成114dns后直接无法使用。

我买的是最便宜的ECS,但不知道为何没有SWAP分区,512Mb内存在起了LXC后又编译了一个东西就超了,那里怎么都不行,于是加了SWAP,可以。

RDS

我想用聚石塔的推送服务,就是可以把订单、商品等数据推送到买的RDS中,但今天申请的时候对方说应用未上线,不能申请。。。我就是需要这些数据才能开发应用,这不就变成死锁了?

2015年1月7日:后来和客服沟通,说是应用需要先上线,即便你还没有开始开发,这点虽然有点怪怪的,但只有这样才能申请到同步服务。应用上线挺简单,创建完应用只是第一步,完善基本信息后点下一步即可进入安全扫描阶段,再提交,瞬间说审核通过,这就上线运行了。

2015年1月9日:商家后台应用有web和客户端两种架构方式,就是你做出一个web应用,一般就是用web的架构方式,用户登陆、授权后,你能拿到用户session,然后就可以用了,和大多数oauth的方式一样,客户端类似。但有一点需要注意,商家后台应用拿到用户的session和refresh token后,文档记载session有效期1年,但这个refresh token无用,只能等session到期后重新授权。

真正开始做了,发现API用起来也不那么爽,这个具体看个人的感觉了,但比拍拍强了不少。


目前就遇到这些坑,欢迎更新坑们。

Host-octopress-blog-on-raspberry-pi

First post on 2015!

I have a raspberry pi several months ago, and I often use it to recording temp and humidity, uploading to a cloud host, but after a home movement, it had been stored in my drawer. Last day of 2014, while waiting 2015, I want build it and host an external disk for MacBookPro backup(Time Machine), but failed for power supply, normal power supply is not enough for raspi, so I should buy another USB Hub powered by itself.

My raspi used a wireless NIC to connecting with my router(OpenWrt), but I want use a ethernet cable for it, so it can get a unique IP on Internet, but when I pluged it, the wireless NIC would down, because of ifplugd or something else, so I keep the wireless NIC working and add some rules on route, port forward, WAN 80 to rasp 80, WAN 443 to rasp 443.

Install nginx viasudo apt-get install nginx, remove default siterm /etc/nginx/sites-enable/default, add conf in /etc/nginx/conf.d, like this:

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
server {
  listen 80;
  server_name dawncold.me;
  return 301 https://$server_name$request_uri;
}

# HTTPS server

server {
  listen 443 ssl;
  server_name dawncold.me;

  root /usr/share/nginx/dawncold.me;
  index index.html index.htm;

  ssl on;
  ssl_certificate /usr/share/nginx/dawncold.me/dawncold.me.crt;
  ssl_certificate_key /usr/share/nginx/dawncold.me/dawncold.me.key;

  ssl_session_timeout 5m;

  ssl_protocols SSLv3 TLSv1;
  ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
  ssl_prefer_server_ciphers on;

  location / {
      try_files $uri $uri/ =404;
  }
}

I got a SSL certificate from nc.me(github student pack), so I rewrite HTTP to HTTPS.

start nginx via sudo nginx or reload config via sudo nginx -s reload.

Oh, your should update your domain A record to your router WAN ip address, you can write a script or use your router buildin DDNS function.

Octopress supported rsync publishment, so edit your Rakefile and enter your raspi ssh account and nginx html root path, like /usr/share/nginx/www.

publish to github and rasp: rake gen_deploy rsync or only to raspi: rake rsync.

NotImplemented-in-python

It’s best to return NotImplemented in magic method(e.g. __eq__, __ne__, etc), see here for details.

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
# example.py

class A(object):
    def __init__(self, value):
        self.value = value

    def __eq__(self, other):
        if isinstance(other, A):
            print('Comparing an A with an A')
            return other.value == self.value
        if isinstance(other, B):
            print('Comparing an A with a B')
            return other.value == self.value
        print('Could not compare A with the other class')
        return NotImplemented

class B(object):
    def __init__(self, value):
        self.value = value

    def __eq__(self, other):
        if isinstance(other, B):
            print('Comparing a B with another B')
            return other.value == self.value
        print('Could not compare B with the other class')
        return NotImplemented

a is instance of ClassA, and b is instance of ClassB, if we invoke a == b, we will get the result, True or False, but if we invoke b == a, we will also get the result! Because of we return NotImplemented in Class B’s __eq__ method, runtime could invoke Class A’s __eq__, that method can compare A and B.

Safe Characters of Quote Method in Urllib

quote accept two arguments: a string and safe characters. If you pass empty to quote as the second parameter, it means every characters except preserved characters will be replaced by a % leading characters, e.g. space will be replaced by %20, etc.

In my project, I invoke quote like quote(params, ''), and I have imported unicode_literals, so I passed a unicode parameter to quote method.

What will happen?

Next time you invoke quote with the same safe parameter you used before, you may get an error like UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128), urllib will cache the safe parameter(urllib.py 1277 line), it expects a byte type parameter but you pass an unicode one, also, that library didn’t check or convert it before it uses.

Best practice, pass a byte parameter like b'' to quote if you have same usage(unicode literals) like me.

Linux-study

directory permission x means this directory can be work directory, if you want to write or read a file behind this directory, you must have permission x of this directory.

directory permission w means you can delete or create files or directories behind this

usr = unix software resource

“-” means last work directory(cd /mnt;cd;cd -)

umask means default permission minus this mask, e.g default new directory 777, if mask is 022, then you will get 777-022——>755 directory; default new file 666, is mask is 002, then you will get 666 - 002——>664 file. mask only can be set in (1, 2, 4) every bit, one bit means the sum of one permission group(current/group/others). umask is based on user, default root has a 0022 mask, normal user has a 0002 mask.

lsattr/chattr is available on ext2/ext3 filesystem, add ‘+i’ attribute can lock one file, no edit or delete, even you are root, ‘+a’ attribute can let a file only accept append content, etc.

SUID, SGID, SBIT special permission: there is a ’s’ on x position of user part, like ‘rws- - - - - -‘. SUID can only set to binary program, if user has x permission of this binary, it can temporarily get the owner permission of this binary, e.g binary ‘passwd’ and /etc/shadow file, shadow only can be updated by root, but every user can change their password via ‘passwd’, it means the user temporarily get owner(root) permission by SUID special permission. SGID similar as SUID, there will be a ’s’ on x position of group part like ‘rwx- - s - - x’. if a user can execute binary, he will temporarily get owner permission, e.g binary ‘locate’ and file ‘mlocate.db’. SGID can be set on a directory, it means if a user have r and x permission of one directory, and ’s’ set on this directory, this user can create a file which owner group is this directory’s. SBIT(Sticky BIT) only set to directory, if a directory has this permission, a user who can create file or directory on this directory, the new file or new directory can only delete by root or himself, e.g /tmp directory, root can delete your new file, and you can also delete it, but others can not. SUID = 4, SGID = 2, SBIT = 1, chmod x755 xxx_file, x means sum of SUID, SGID, SBIT, if omit, this bit is zero, if you set a invalid SUID/SGID/SBIT, there will be upper case S/T, lower case is valid.

find / -size 1M -exec ls -l {} \; {} means the args from find, “\;” means the end of “exec”, commands in exec can not use alias.

Aix-security

some security configuration for AIX ssh and system services

create a user group named rmt_acc, only allow this group user access ssh, don’t allow root login and use public key authentication.

sshd_config content

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# $OpenBSD: sshd_config,v 1.77 2008/02/08 23:24:07 djm Exp $


# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.


# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin


# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options change a
# default value.


#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::


# Disable legacy (protocol version 1) support in the server for new
# installations. In future the default will change to require explicit
# activation of protocol 1
Protocol 2


# HostKey for protocol version 1
#HostKey /etc/ssh/ssh_host_key
# HostKeys for protocol version 2
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key


# Lifetime and size of ephemeral version 1 server key
#KeyRegenerationInterval 1h
#ServerKeyBits 768


# Logging
# obsoletes QuietMode and FascistLogging
#SyslogFacility AUTH
#LogLevel INFO


# Authentication:


#LoginGraceTime 2m
PermitRootLogin no
StrictModes yes
#MaxAuthTries 6


#RSAAuthentication yes
PubkeyAuthentication yes
#AuthorizedKeysFile .ssh/authorized_keys


# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#RhostsRSAAuthentication no
# similar for protocol version 2
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# RhostsRSAAuthentication and HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes


# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no
PermitEmptyPasswords no


# Change to no to disable s/key passwords
ChallengeResponseAuthentication no


# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no


# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes


# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes


#AllowTcpForwarding yes
#GatewayPorts no
#X11Forwarding no
#X11DisplayOffset 10
#X11UseLocalhost yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
UsePrivilegeSeparation yes
#PermitUserEnvironment no
#Compression delayed
ClientAliveInterval 600
ClientAliveCountMax 0
#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10
PermitTunnel no
#ChrootDirectory none


# no default banner path
#Banner none


# override default of no subsystems
Subsystem sftp /usr/sbin/sftp-server


# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# ForceCommand cvs server


AllowGroups rmt_acc

install sudo for AIX

1
rpm -i sudo-for-aix.rpm

stop telnet/login/ftp/shell/exec service:

don’t start telnet if reboot:

comment the line starts with ‘telnet’/‘login’/‘ftp’/‘shell’/‘exec’ in /etc/inetd.conf

1
stopsrc -t telnet