nginx / IPv6 在 Linux 下访客 IP 问题的解决

之前配置好了 nginxIPv6 ,并让 nginx 同时监听 IPv4 和 IPv6 地址,今天突然发现 PHP 的 getenv("REMOTE_ADDR"); 甚至 nginx 日志在获取使用 IPv4 的访客 IP 时有些问题,一概显示成了类似于 ::ffff:111.222.111.222 这种 IPv6 格式。到 nginx 的 wiki 搜索后发现了问题所在:原来 Linux 默认情况下所有的 IPv6 TCP socket 都可以通过将 IPv4 地址转换为 IPv6 地址的格式从而处理来自于 IPv4 的连接,这也就是为什么 Linux 下面的 nginx 写一个 listen [::]:80 即可 4/6 通吃的原因,但是这样就造成了客户的 IPv4 地址被翻译成了 IPv6 的格式,从而造成 php 以及其他程序无法获取客户的 IPv4 地址。这样显然问题多多,如果某个程序保存客户 IP 地址这个字段不够长的话很容易出现问题。

解决办法是在 /etc/sysctl.conf 中加入一行

net.ipv6.bindv6only=1

之后

sysctl -p

即可关闭 Linux 的这一 bug feature,之后记得修改 nginx 的配置文件,加入 IPv4 的监听配置

PS:FreeBSD 默认 IPv4 和 IPv6 就是分开处理的,需要分别 listen。

Posted in 我的慵懒生活, 电脑相关 | Tagged , , , | 3 Comments

使用 Startssl 提供的免费证书+Nginx 搭建 https 的网站

nginx_ssl_1

Startssl 是一家提供免费 SSL 证书的公司,我们可以用其搭建 https 网站,貌似可以被除去 Opera 外的所有主流浏览器所信任,过程简单记录如下:

  1. 打开 http://www.startssl.com/ ,注册一个用户,注意这个网站是用证书验证用户身份的,所以证书一定备份好。另外。。。不支持 Chrome,用 Safari 吧。
  2. 登陆后进入 Validations Wizard,验证你要添加 ssl 支持的域名。
  3. 进入 Certificates Wizard,并选择 Web Servers SSL/TLS Certificates。
  4. 创建一个 private key,连同密码一起保管好。(或者你也可以自己在服务器上用 openssl 创建,这里点skip就行了)
  5. 选择一个域名,以及子域名。
  6. 网站会给出证书,保存为 .csr 文件。
  7. 使用 Tool Box 里面的 Decrypt Private Key 或者自己用 openssl 将第4步生成的 private key 解密,并将结果保存为 .key 文件。
  8. 按照修改 nginx 默认的虚拟主机配置文件的范例修改,关键语句如下:

listen          443;
ssl                     on;
ssl_certificate         /etc/nginx/certs/xxxxxx.crt;
ssl_certificate_key     /etc/nginx/certs/xxxxxx.key;
ssl_session_timeout     5m;

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

fast_cgi 部分也加入一行:

fastcgi_param   HTTPS on;

另外在这里看到,中文版 Firefox 貌似不会信任这个证书,需要下载 Startcom 的根证书并且附在网站证书后面:

wget http://www.startssl.com/certs/ca.pem 感谢 @startssl 的亲自指正,这个是错误的,应该是:
wget http://www.startssl.com/certs/sub.class1.server.ca.pem
cat sub.class1.server.ca.pem >> xxxxx.crt

重新启动 nginx,即可顺利使用 https 打开虚拟主机了。

nginx_ssl_2 

顺便说一下,Startcom 这个公司貌似有很多人在管理证书颁发这个事情,他们的邮件回复总是非常快。比如上次我想给 img.gd 申请证书,结果发现他们的域名选择里面没有 .gd,于是给他们发去了邮件,Startcom就回信问我要了管理机构网址以及 whois 地址,我回给他们后很快就又收到邮件告诉我说可以用了。再有就是昨天想给谷奥申请一个,结果系统提示申请需要手工审核,并且随后被拒绝,发信过去问原因,告知我 Google 是著名商标,除非我有 Google 的授权,否则他们不会给这个域名颁发证书,于是只好放弃。

Posted in 我的慵懒生活 | Tagged , | 1 Comment

Discuz 在 nginx+fastcgi 环境下相对路径问题的解决

这几天在陆续用 apache 替换成 nginx,发现所有在用的 discuz 都出现了 php 脚本中相对路径的问题。比如 discuz 动态头像调用是类似于:

http://www.xxx.com/ucenter/avatar.php?uid=21480&size=middle

但是调用后的地址就变成了:

http://www.xxx.com/ucenter/avatar.php/ucenter/data/images/000/05/60/39_avatar_middle.jpg

查看源代码发现,discuz 中的相对路径都是直接写的文件名,前面没有 ./,与此同时还带来了批量上传 flash 文件无法调用 misc.php 导致提示文字无法显示,引用及提醒信息跳转地址错误等,一概都是由于指向了错误的 xxx.php/dir 这样的 url。感觉不应该是 nginx 的问题,于是查看 php.ini 相关设置,发现 cgi.fix_pathinfo 这个选项正是解决问题的关键,将这个值设置为 0 的话,PATH_TRANSLATED 将等同于 SCRIPT_FILENAME,之后重启 php-fpm 后 discuz 的这个问题就解决了。看来还是 discuz 7.2 代码兼容性的问题,不知道更新的 dzx 是否已经有所改进了?

UPDATE:发现今年5月有一个相关的 nginx 漏洞,可以参考。

Posted in 我的慵懒生活 | Tagged , , | 2 Comments

把 Terminal 拆成多个窗口的 tmux

今天 @delphij 介绍了一个 terminal 神器 - tmux,可以打开10个窗口而且每个窗口都可以随便切分,实在是赞到飞起,从此不用再一下开好几个 ssh 连接了。

在 tmux 主页下载源代码,FreeBSD / Linux 编译安装都很方便,Linux 下面可能会提示找不到 event.h 以及 curses.h 等,分别安装 libevent-dev 和 ncurses-dev 就行了。

启动后默认按 ctrl+b 进入命令输入,? 可以查看命令,支持自定义快捷键。退出用 d 命令,以后用 tmux attach 启动即可直接恢复上次的 session,很好很强大。

Posted in 电脑相关 | Tagged , | 5 Comments

mysql 升级后的连锁反应

上次由于 mysql replication 的问题把一台原先跑 mysql 5.0 的服务器升级到了  mysql 5.1,升级后果然 replication 再没出现过问题。但是今天突然发现 postfix 无法启动,检查日志发现很多类似提示:

postfix/smtpd[1485]: fatal: no SASL authentication mechanisms

检查一下,发现 dovecot 没有起来,手工启动也失败,继续检查日志,发现

dovecot: auth(default): /libexec/ld-elf.so.1: Shared object "libmysqlclient.so.15" not found, required by "dovecot-auth"

到 /usr/local/mysql/lib 一看傻眼了,mysql 5.1 的 client 库也变了,是 libmysqlclient.so.16 了,而 dovecot 还在找 5.0 的 .15,所以显然无法启动。

尝试耍鸡贼 ln -s  libmysqlclient.so.15 libmysqlclient.so.16,启动 dovecot:

auth(default): /libexec/ld-elf.so.1: /usr/local/lib/mysql/libmysqlclient.so.15: version libmysqlclient_15 required by /usr/local/libexec/dovecot/dovecot-auth not found

骗不过去。。只好重新安装 dovecot 了。。。

cd /usr/ports/mail/dovecot
sudo make deinstall
sudo make reinstall
/usr/local/etc/rc.d/dovecot start

启动成功,postfix 恢复正常。服务器上这些东西真是牵一发而动全身呀,所以没事还是别折腾的好,弄不好就得被迫升级一大堆相关联的东西。

UPDATE:经 @delphij 大婶点拨,可以直接用

portmaster -Bdv dovecot

重装 dovecot

Posted in 我的慵懒生活, 电脑相关 | Tagged , , | 1 Comment

尝试把谷奥的 http server 换成了 nginx

周末没有太多事情,于是尝试把谷奥的 http server 换成了 nginx,一开始 rewrite 怎么也不生效,后来 pkg_delete 后重新安装就好了,中间也没改 config,真是怪了。。。目前看来问题不大,还需继续观察。

顺便做了个性能测试,webbench -c 100 -t 30 phpinfo(),nginx 使用了 kqueue 参数。

apache 2 的结果:

Benchmarking: GET phpinfo.php
100 clients, running 30 s

Speed=1398 pages/min, 1272384 bytes/sec.
Requests: 699 susceed, 0 failed.

Nginx 的结果:

Benchmarking: GET phpinfo.php
100 clients, running 30 sec.

Speed=19628 pages/min, 19852940 bytes/sec.
Requests: 9814 susceed, 0 failed.

差了10多倍啊!

Posted in 我的慵懒生活, 电脑相关 | Tagged , , , | 3 Comments

使用 OpenVPN 将 HE Tunnel Broker 的 IPv6 搬回家

ipv6google

之前我们已经给 VPS 配置好了 HE Tunnel Broker 提供的 IPv6 地址,但是这 2^80 个 IPv6 地址都放在服务器上有些太浪费了,为何不弄到家里电脑来,让家里电脑也可以使用 IPv6 呢?等着国内运营商提供 IPv6 恐怕得猴年马月了吧?

Google 了一下,使用 OpenVPN Tunnel 可以轻松完成这个工作,有两种方法:第一种是用 tap 模式建立网桥,服务器端运行 radvd 给客户端分配 IPv6 地址并作路由。第二种使用 sit 设备,不需要配置服务,但是需要客户端做相应的绑定。我选择第二种,主要是想将 OpenVPN 维持在 tun 模式。

基本思路是根据给客户端分配的内部 IPv4 地址的最后一位(X)在服务器端(在 Debian / Ubuntu 测试通过)起一个 sitX 设备,并且绑定 2001:1111:2222:X::1 这个地址,同时客户端(我这里是 Mac OS X,Windows / Linux 也可以分别使用批处理 / Bash 脚本调用 ip 命令搞定) gif 设备绑定 2001:1111:2222:X::2,并将默认路由设置为 2001:1111:2222:X::1,从而实现 IPv6 通路。下面是简单的设置过程和脚本文件:

服务器端设置:

vi /etc/openvpn/server.conf

最后加入:

script-security 2
client-connect /etc/openvpn/client-connect.sh
client-disconnect /etc/openvpn/client-disconnect.sh

编辑客户连接脚本

vi /etc/openvpn/client-connect.sh

内容:

Continue reading

Posted in 我的工作学习, 电脑相关 | Tagged , , , | 4 Comments

使用 he.net 的 Tunnel Broker 为 vps 设置 IPv6 连接

ipv6_ready

并不是所有 VPS 供应商都会给你配备 IPv6 地址,包括备受赞誉的 Linode 也是一样,这时候我们可以使用 he.net 提供的 Tunnel Broker 服务。进入 http://tunnelbroker.net/ 注册一个用户名,并且输入 vps 的 ip ,选择一个距离 vps 最近的接入节点,创建一个 Regular Tunnel,之后打开 Tunnel Detail 就可以看到给你分配的 IPv6 地址,以及 IPv6 网关和 IPv4 节点地址了。之后进行 vps 段设置,编辑 /etc/network/interfaces,加入如下内容:

auto hetunnel
       iface hetunnel inet6 v4tunnel
               address HESupplied-ClientIPv6address
               netmask 64
               ttl 64
               gateway HESupplied-ServerIPv6address
               endpoint HESupplied-ServerIPv4address
               local localIPv4address

sudo /etc/init.d/networking restart 后,试试看 ping6 ipv6.google.com 吧:

gkp@gkplinode:~$ ping6 ipv6.google.com
PING ipv6.google.com(yu-in-x63.1e100.net) 56 data bytes
64 bytes from yu-in-x63.1e100.net: icmp_seq=1 ttl=56 time=49.2 ms
64 bytes from yu-in-x63.1e100.net: icmp_seq=2 ttl=56 time=49.2 ms
64 bytes from yu-in-x63.1e100.net: icmp_seq=3 ttl=56 time=49.2 ms
64 bytes from yu-in-x63.1e100.net: icmp_seq=4 ttl=56 time=49.4 ms

之后为域名加入 AAAA 解析记录,dig 看看效果:

[gkp@home] ~> dig img.gd aaaa

; <<>> DiG 9.6.2-P2 <<>> img.gd aaaa
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30063
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;img.gd.                                IN      AAAA

;; ANSWER SECTION:
img.gd.                 3600    IN      AAAA    2001:470:1f0e:541::2

;; Query time: 612 msec
;; SERVER: 202.106.0.20#53(202.106.0.20)
;; WHEN: Wed Sep 22 18:58:26 2010
;; MSG SIZE  rcvd: 52

接下来设置 apache,编辑 /etc/apache2/ports.conf,加入一行

Listen [::]:80

之后重新启动 apache 即可支持 IPv6 访问。

Nginx 的话,需要先 nginx –V 一下,看看编译时有没有加入 –with-ipv6 这个选项,有的话就可以直接编辑虚拟主机文件了,将 Listen 80 这行直接改成:

Listen [::]:80

即可,如果只想监听 IPv6 而不支持 IPv4 的话,可以用:

Listen [::]:80 default ipv6only=on;

Posted in 电脑相关 | Tagged , , , | 9 Comments

mysqlbinlog Error in Log_event 原因及其解决

话说昨天配置好了 mysql 的 replication,今天到 slave 上 show slave status 却发现出错了,错误日志里面这么说的:

100921 21:49:10 [ERROR] Error in Log_event::read_log_event(): 'Found invalid event in binary log', data_len: 80, event_type: 19
100921 21:49:10 [ERROR] Error reading relay log event: slave SQL thread aborted because of I/O error
100921 21:49:10 [ERROR] Slave: Could not parse relay log event entry. The possible reasons are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log), the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's or slave's MySQL code. If you want to check the master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave. Error_code: 0
100921 21:49:10 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'mysql-bin.000293' position 616316942

到 Google 搜索了一下这个问题,发现貌似是 mysqlbinlog 这个程序的版本问题,仔细一看我的 master 跑的是 mysql-server 5.1,mysqlbinlog 版本是 3.3,而 slave 的 mysql-server 是 5.0,mysqlbinlog 是 3.2 版,于是备份好数据尝试升级:

pkg_delete -f mysql\*
cd /usr/ports/mysql51-server
make install clean

貌似没出问题,然后 skip-slave-start 启动 mysql-server,恢复断点:

mysql> CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000293' , MASTER_LOG_POS=616316942;
mysql> slave start;
mysql> show slave status;

看到 Slave_IO_Running 和 Slave_SQL_Running 都是 YES 应该就恢复 replication 了,对比一下两边的数据,应该是正常的。至于这个错误到底是不是 mysqlbinlog 版本的问题,只能观察几天看看了。

UPDATE:升级后,跑了5天没有再出现类似问题,不过 mysql 升级后还是带来了一些连锁反应,见这里

Posted in 我的慵懒生活, 电脑相关 | Tagged , | 2 Comments

配置 master-slave replication mysql 服务器笔记

对于服务器来说,数据丢失是最要命的事情了,系统崩溃,硬盘物理损坏都可能造成无法挽回的损失。谷奥数据库的备份也一直是我心头之病,最近有空架设了一台 slave 服务器并且在 slave 服务器上用 crontab 保留 snapshot,数据安全性应该有了比较大的改善了。简单配置过程如下,环境为 mysql 5.0 / 5.1 + FreeBSD 8.1

master 服务器,首先修改 my.cnf:

sudo vi /var/db/mysql/my.cnf

修改或加入如下行,binlog-ignore-db 可以根据自己实际情况修改

log-bin=mysql-bin
server-id       = 1
binlog-ignore-db=mysql,information_schema

重新启动 mysql-server

sudo /usr/local/etc/rc.d/mysql-server restart

进入 mysql console,加 slave 用户:

mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@SLAVE_IP_ADDRESS IDENTIFIED BY 'PASSWORD';
mysql> FLUSH PRIVILEGES;

查看 master 的数据,记得先锁定表格:

mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS;

记下其中的 File 文件名和 Position 执行位置,下一步导出 master 的数据,推荐使用 tar 直接打包然后解压到 slave 的数据库目录内。tar 或者 mysqldump 完毕后就可以解锁表格了。

mysql> UNLOCK TABLES:

接下来进行 slave 设置,修改 my.cnf 设置

Continue reading

Posted in 电脑相关 | Tagged , , | 2 Comments