作者归档:Neil

ssh 使用public key 免密码登录

 

第一步,生成自己公钥, 私钥

 

   1:  ssh-keygen -t rsa
   2:   
   3:  root@yjlml:~# ssh-keygen -t rsa
   4:  Generating public/private rsa key pair.
   5:  Enter file in which to save the key (/root/.ssh/id_rsa): 
   6:  Enter passphrase (empty for no passphrase): 
   7:  Enter same passphrase again: 
   8:  Your identification has been saved in /root/.ssh/id_rsa.
   9:  Your public key has been saved in /root/.ssh/id_rsa.pub.
  10:  The key fingerprint is:
  11:  3e:6e:d9:12:7c:f8:6f:18:f6:65:cb:6e:16:4f:83:43 root@yjlml
  12:  The key's randomart image is:
  13:  +--[ RSA 2048]----+
  14:  |                 |
  15:  |                 |
  16:  |                 |
  17:  |             E   |
  18:  |       .S.  . .  |
  19:  |       .+ +  o+..|
  20:  |        oB + +.=.|
  21:  |       .+.+ o = .|
  22:  |       ... o.+.  |
  23:  +-----------------+

 

中间连续按几次回车, 使用默认文件名, 并不输入密码。

 

二, 把你的公钥,拷贝到远程机器的  “~/.ssh/authorized_keys” 文件中。

刚才生成的公钥在: ~/.ssh/id_rsa.pub,  里面是文本,直接复制出来,粘贴到远程的“~/.ssh/authorized_keys” 文件中即可。 如果没有这个文件,自己新建一个。

这个文件可以保存多个公钥,只需要连续放在里面就可以了。

拷贝的方法有很多。自己想办法。

 

拷贝完成之后,重启一下ssh服务。

service ssh  restart

 

然后测试是否成功:

   1:  root@yjlml:~# ssh root@190.***.***.***  -p 22   ls

这里故意指定了一个端口22, 其实可以省略的。如果你的ssh端口不是22可以这样指定。

这句话是在远程执行一个 命令 ls, 看能不能执行成功。

如果能看到ls的结果。那就是成功了。

 

 

三, 错误处理

如果访问不成功,请检查远程机器的 “/etc/ssh/sshd_config ”文件:

找到其中的这一段。

   6:  RSAAuthentication yes
   7:  PubkeyAuthentication yes
   8:  #AuthorizedKeysFile    %h/.ssh/authorized_keys

 

image

 

注意,必须开启 公钥认证, 检查公钥文件。

 

改完之后,重启远程ssh服务: service ssh  restart

翻译,NTLM和频道绑定哈希(EPA)

为了过NTLM 的EPA认证, 参考了这篇文章,现在翻译过来,备查。

如果你知道NTLM,并且需要过EPA, 那么这篇文章一定是你最想知道的。

原文地址:

NTLM and Channel Binding Hash (aka Extended Protection for Authentication) - Microsoft Open Spec

 

=======================

Extended Protection for Authnetication (EPA) was introduced in Windows 7/WS2008R2 to thwart reflection attacks. This blog describes the changes in the implementation of NTLM Authentication that are needed to successfully authenticate to servers that have EPA enabled. Windows 7/WS 2008R2 and Windows 8/ WS2012 have EPA enabled out of the box.

认证的扩展保护(EPA) 在Windows7/WS2008R2 中引进, 用来对抗反射攻击. 本文介绍了要通过服务器端EPA认证,NTLM实现上的必要的改变.  Windows7/WS2008R2 和Windows8/WS2012默认开启了EPA.

You can read the details about EPA here http://technet.microsoft.com/en-us/security/advisory/973811

这里有EPA进一步的细节.

The concept in EPA is that authentication packets should be bound to the secure channel on which they are transmitted. This concept is not new and is known as channel binding (RFC 5056). RFC 5929 describes channel bindings for TLS that Winodws uses to bind the secure channel to authentication. Please note that EPA also uses Service Pricipal Name (SPN) but it is not used for TLS and we will not discuss it here.

EPA的概念是认证的数据包应该绑定到传输它的安全频道上.  这个概念并不是全新的, 它就是众所周知的频道绑定(RFC5056).  RFC5929描述了描述了Tls的频道绑定, Windows用它绑定安全频道到认证.  请注意, EPA同样也使用了服务主体名称(SPN), 但是这没有被用于TLS, 我们在这不讨论它.

Let's take an example of HTTPS, a protocol that uses TLS. Once a secure channel is established and cipher change has happened, HTTP traffic starts flowing. In this example, we are only considering services that require authentication. NTLM or Kerberos will be used if you are using Windows authentication. You are most likely to use NTLM since the whole point of using HTTP and TLS is to allow clients to connect over internet (In Windows 8, Kerberos can be used on the internet but we will concentrate on NTLM here). In case of Windows client, these are the steps that are taken to incorporate channel binding in the authentication process after secure channel has been established:

我们看看HTTPS协议, 它使用了TLS.  一旦安全频道建立,并且密码交换完成, HTTP就开始传输.  在这个例子中, 我们只关心需要认证的服务.  如果你正在使用Wndows认证的话, NTLM或者Kerberos将会被应用.你很可能会使用NTLM,  因为在TLS上使用HTTP的全部原因就是允许客户端通过Internet连接. (在Windows8中, Kerberos也能引用于internet, 但是我们仍然集中在NTLM上.) 对于Windows客户端,  在安全频道建立之后, 认证过程中, 构成频道绑定的步骤如下:

1. The hashing algorithm for the signature in the certificate is identified, if present.

如果存在, 证书签名的哈希算法先被识别出来.

2. SSPI calculates a hash (almost always SHA256 hash, see below for details/exceptions) of the certificate, appends other data relevent to the type of channel bindings and returns it to the application.

SSPI 计算证书的哈希值(通常是SHA256, 后面会有细节和例外),  加上频道绑定类型的相关数据, 然后返回给应用程序.

4. SSPI calculates the MD5 hash of channel bindings and uses it in the calculation of NTLM version 2 response.

SSPI 计算频道绑定的MD5哈希值,  用于计算 NTLM version 2 的回复

5. When server recives authenticate message, it queries SSPI for channel bindings. SSPI does exactly the same thing as on the client side and returns the data to the service. The service includes it in the call to method Accept Security Context (ASC)

当服务器接收到认证消息之后, 它像SSPI查询频道绑定.  SSPI 进行域客户端完全一样的操作, 并把数据返回给服务.  服务端在 接受安全上下文(ASC)的调用中包含这个数据.

6. In the process of verifying authenticate message, SSPI also takes into account the channel bindings. It calculates the MD5 hash of the channel bindings that were provided by the application (service) and compares it to the one sent by the client. If they match and rest of the authentication requirements are met, authentication is successful.

在校验的认证消息的过程中, SSPI同样要考虑频道绑定. 它会计算应用(服务)提供的频道绑定的MD5值, 并且和客户端发送过来的值进行对比.  如果匹配, 并且人权衡的其他条件满足, 则认证成功.

I'll now elaborate on each of the step listed above with a concrete example of RPC-over-HTTP traffic. The TLS network traffic is encrypted and I used Network Monitor expert Network Monitor Decryption Expert (NmDecrypt) to decrypt it. The decrypted network trace is attached to this blog.

下面使用一个具体的 RPC-over-HTTP 的传输来具体描述上面的每一步.  Tls的网络传输都是加密的, 我使用了 Network Monitor expert Network Monitor Decryption Expert (NmDecrypt) 来解密. 解密的网络跟踪在帖子的附件中.

If you open the network trace in Network Monitor, you'll see that in frame 16 server sends a certificate to client, as below (copied and pasted from the trace):

打开 网络跟踪日志, 你会发现在第16帧, 服务端发送了一个证书给客户端, 如下:

......

After secure channel is established and cipher change has taken place, HTTP traffic starts flowing.

在安全频道建立之后,并且密码交换完成, HTTP传输就开始了.

In this example, HTTP is being used as a transport for RPC and RPC server requires authentication. For authentication, the client application first calculates the channel binding by using the following process(in Windows this is done by SSPI but that is not important in this discussion ). This process is based on RFC 5929.

在这个例子中, HTTP用来传输RPC, 并且RPC服务器要求认证.  对于认证, 客户端首先计算频道绑定, 过程如下(在Windows中, 由SSPI完成, 但这不重要): 这个过程基于RFC5929.

1. The channel binding type for this example is "tls-server-end-point" since a certificate is used in handshake (RFC5929).

频道绑定类型在本例中是 "tls-server-end-point", 因为在握手时使用了证书.

2. The client calculates a hash of the certificate. The hashing algorithm is SHA-256, unless all of the following conditions are met, in which case the signature algorithm in the certificate will be used.

客户端计算证书的哈希值. 哈希算法是SHA256, 除非下面的条件都满足, 此时将会使用证书的签名算法.

A certificate signature algorithm exist

证书签名算法存在

The algorithm is only implemented in CNG (ALG_ID is CALG_OID_INFO_CNG_ONLY)

(证书签名)算法只在CNG中实现(ALG_ID 为 CALG_OID_INFO_CNG_ONLY).

The algorithm has a corresponding CNG algorithm identifier string (pwszCNGAlgid)

(证书签名)算法有相应的CNG算法标示字符串(pwszCNGAlgid)

The algorithm is not SHA1

算法不是SHA1

The algorithm is not MD5

算法不是MD5

3. The SHA-256 hash of the above certificate is: ea 05 fe fe cc 6b 0b d5 71 db bc 5b aa 3e d4 53 86 d0 44 68 35 f7 b7 4c 85 62 1b 99 83 47 5f 95

上面证书的SHA-256哈希值是:  ea 05 fe fe cc 6b 0b d5 71 db bc 5b aa 3e d4 53 86 d0 44 68 35 f7 b7 4c 85 62 1b 99 83 47 5f 95

4. The Channel binding unique prefix (RFC5929) "tls-server-end-point" is prefixed to the hash above (with a colon), resulting in 

74 6c 73 2d 73 65 72 76 65 72 2d 65 6e 64 2d 70 6f 69 6e 74 3a ea 05 fe fe cc 6b 0b d5 71 db bc 5b aa 3e d4 53 86 d0 44 68 35 f7 b7 4c 85 62 1b 99 83 47 5f 95

频道绑定前缀"tls-server-end-point"被附加到这个hash值得前面(冒号分隔):

74 6c 73 2d 73 65 72 76 65 72 2d 65 6e 64 2d 70 6f 69 6e 74 3a ea 05 fe fe cc 6b 0b d5 71 db bc 5b aa 3e d4 53 86 d0 44 68 35 f7 b7 4c 85 62 1b 99 83 47 5f 95

5. The above value is inserted as the value of application_data field of gss_channel_bindings_struct structure, as pointed out by MS-NLMP section 2.2.2.1

上面这个值插入到 gss_channel_bindings_struct 结构的 application_data 字段 .  这个字段在  MS-NLMP section 2.2.2.1 描述.

6. Windows always sets the other fields of gss_channel_bindings_struct as zeros (SEC_CHANNEL_BINDINGS

structure). The resulting gss_channel_bindings_struct is as follows (little endian format):

Windows 总是将 gss_channel_bindings_struct 机构的其他字段设为 0.  gss_channel_bindings_struct 结构的结果如下(小端格式):

00 00 00 00 //initiator_addtype 

00 00 00 00 //initiator_address length

00 00 00 00 //initiator_address pointer

00 00 00 00 //acceptor_addrtype

00 00 00 00 //acceptor_address length

00 00 00 00 //acceptor_address pointer

35 00 00 00 //application_data length (53 bytes)

20 00 00 00 //application_data pointer (32 bytes from start of this structure)

74 6c 73 2d //application data, as calculated above

73 65 72 76

65 72 2d 65

6e 64 2d 70

6f 69 6e 74

3a ea 05 fe

fe cc 6b 0b

d5 71 db bc

5b aa 3e d4

53 86 d0 44

68 35 f7 b7

4c 85 62 1b

99 83 47 5f

95

After calculating channel binding, the client application starts authentication and include channel binding as part of authentication. In case of NTLM, the gss_channel_bindings_struct is called ClientChannelBindingUnhashed (MS-NLMP section 3.1.1.2). As explained in MS-NLMP section 3.1.5.1.2, the client adds an AV_PAIR structure and set the AvId field to MsvAvChannelBindings and the Value field to MD5(ClientChannelBindingsUnhashed). The MD5 hash of the above gss_channel_bindings_struct turns out to be:

频道绑定完成之后, 客户端开始认证, 将频道绑定作为认证的一部分包含进来.  对于NTLM, gss_channel_bindings_struct 结构 被叫做: ClientChannelBindingUnhashed (MS-NLMP section 3.1.1.2). 正如  MS-NLMP section 3.1.5.1.2, 中所介绍的,  客户端添加一个AV_PAIR  结构, AvId字段设为 MsvAvChannelBindings, 而Value字段设为 MD5(ClientChannelBindingsUnhashed). 上面的gss_channel_bindings_struct  结构的MD5值如下:
65 86 E9 9D 81 C2 FC 98 4E 47 17 2F D4 DD 03 10

This value is part of the AUTHENTICATE_MESSAGE in frame 27 in the network trace attached (in the network trace it is shown in Base64 encoding as 45 41 42 6C 68 75 6D 64 67 63 4C 38 6D 45 35 48 46 79 2F 55 33 51 4D 51 with AvLen) .

这个值作为AUTHENTICATE_MESSAGE 认证消息的一部分, 在附件的第27帧(附件中显示为Base64的编码值:   45 41 42 6C 68 75 6D 64 67 63 4C 38 6D 45 35 48 46 79 2F 55 33 51 4D 51 包含 AvLen   ).

When server receives the AUTHENTICATE_MESSAGE, in addition to the regular authentication processing, it also verifies the channel binding hash by calculating it the same way the client did. If the channel binding hash does not match, the authentication will not be successful. The subsequent behavior is server dependent. In this example (IIS), the server will stop communication on unsuccessful authentication.

当服务端收到 AUTHENTICATE_MESSAGE 认证消息之后, 除了做常规的认证处理之外, 它还校验频道绑定数据, 与客户端同样计算一遍. 如果频道绑定数据不匹配, 认证就失败. 之后的行为就和服务器相关. 在这个例子中(IIS), 服务器会停止通信.

Please note that two step hashing is being employed here. First the application creates a hash of the certificate which becomes a part of gss_channel_bindings_struct structure. This structure is MD5 hashed again to be included in AUTHENTICATE_MESSAGE.

请注意, 这里应用了2步哈希. 首先应用程序计算证书的哈希值, 使其成为 gss_channel_bindings_struct结构的一部分.  这个结构又被计算MD5 哈希值, 用来包含在 AUTHENTICATE_MESSAGE中.

There are configurations on both Windows client and server side to disable the EPA. For the server side, please consult the server specific documentation. As for the server in this example, IIS, please consult http://www.iis.net/configreference/system.webserver/security/authentication/windowsauthentication/extendedprotection.

在Windows客户端和服务端都有配置来禁用EPA.  对于服务端, 请参考服务端规范. 对于本例中使用的IIS, 请参考:

http://www.iis.net/configreference/system.webserver/security/authentication/windowsauthentication/extendedprotection

On the client side, there is a registry setting that is described in KB976918 (http://support.microsoft.com/kb/976918) that can be used to configure EPA.

对于客户端,  KB976918 描述了一个注册表设置(http://support.microsoft.com/kb/976918) 能用来配置EPA.

 

==============================

本文不是完全对照翻译,但是力求主题意思清楚。  请参考原文阅读:

NTLM and Channel Binding Hash (aka Extended Protection for Authentication) - Microsoft Open Spec

 

欢迎大家交流讨论。

学一点 mysql 双机异地热备份—-mysql主从,主主备份原理及实践

简单介绍mysql双机,多机异地热备简单原理实战。

双机热备的概念简单说一下,就是要保持两个数据库的状态自动同步。对任何一个数据库的操作都自动应用到另外一个数据库,始终保持两个数据库数据一致。 这样做的好处多。 1. 可以做灾备,其中一个坏了可以切换到另一个。 2. 可以做负载均衡,可以将请求分摊到其中任何一台上,提高网站吞吐量。  对于异地热备,尤其适合灾备。废话不多说了。我们直接进入主题。 我们会主要介绍两部分内容:

一, mysql 备份工作原理

二, 备份实战

 

我们开始。

我使用的是mysql 5.5.34,

 

image

 

一, mysql 备份工作原理

简单的说就是把 一个服务器上执行过的sql语句在别的服务器上也重复执行一遍, 这样只要两个数据库的初态是一样的,那么它们就能一直同步。

 

当然这种复制和重复都是mysql自动实现的,我们只需要配置即可。

 

我们进一步详细介绍原理的细节, 这有一张图:

上图中有两个服务器, 演示了从一个主服务器(master) 把数据同步到从服务器(slave)的过程。

这是一个主-从复制的例子。 主-主互相复制只是把上面的例子反过来再做一遍。 所以我们以这个例子介绍原理。

 

对于一个mysql服务器, 一般有两个线程来负责复制和被复制。当开启复制之后。

 

1. 作为主服务器Master,  会把自己的每一次改动都记录到 二进制日志 Binarylog 中。 (从服务器会负责来读取这个log, 然后在自己那里再执行一遍。)

 

2. 作为从服务器Slave, 会用master上的账号登陆到 master上, 读取master的Binarylog,  写入到自己的中继日志 Relaylog, 然后自己的sql线程会负责读取这个中继日志,并执行一遍。  到这里主服务器上的更改就同步到从服务器上了。

 

在mysql上可以查看当前服务器的主,从状态。 其实就是当前服务器的 Binary(作为主服务器角色)状态和位置。 以及其RelayLog(作为从服务器)的复制进度。

 

例如我们在主服务器上查看主状态:

 

image

mysql> show master status\G
*************************** 1. row ***************************
            File: mysql-bin.000014
        Position: 107
    Binlog_Do_DB: 
Binlog_Ignore_DB: mysql,information_schema,performance_schema,amh
1 row in set (0.00 sec)

稍微解释一下这几行的意思:

1. 第一行表明 当前正在记录的 binarylog文件名是: mysql-bin.000014.

我们可以在mysql数据目录下,找到这个文件:

image

 

2.  第二行, 107. 表示当前的文件偏移量, 就是写入在mysql-bin.000014 文件的记录位置。

这两点就构成了 主服务器的状态。  配置从服务器的时候,需要用到这两个值。 告诉从服务器从哪读取主服务器的数据。 (从服务器会登录之后,找到这个日志文件,并从这个偏移量之后开始复制。)

 

3. 第三行,和第四行,表示需要记录的数据库和需要忽略的数据库。 只有需要记录的数据库,其变化才会被写入到mysql-bin.000014日志文件中。  后面会再次介绍这两个参数。

 

我们还可以在从服务器上,查看从服务器的复制状态。

 

image

 mysql> show slave status\G
 *************************** 1. row ***************************
                Slave_IO_State: Waiting for master to send event
                   Master_Host: 198.**.***.***
                   Master_User: r*******
                   Master_Port: 3306
                 Connect_Retry: 60
               Master_Log_File: mysql-bin.000014
           Read_Master_Log_Pos: 107
                Relay_Log_File: mysqld-relay-bin.000013
                 Relay_Log_Pos: 253
         Relay_Master_Log_File: mysql-bin.000014
              Slave_IO_Running: Yes
             Slave_SQL_Running: Yes
               Replicate_Do_DB:
           Replicate_Ignore_DB: mysql,information_schema,amh,performance_schema
            Replicate_Do_Table:
        Replicate_Ignore_Table:
       Replicate_Wild_Do_Table:
   Replicate_Wild_Ignore_Table:
                    Last_Errno: 0
                    Last_Error:
                  Skip_Counter: 0
           Exec_Master_Log_Pos: 107
               Relay_Log_Space: 556
               Until_Condition: None
                Until_Log_File:
                 Until_Log_Pos: 0
            Master_SSL_Allowed: No

 

我们还是来重点解释途中的红圈的部分:

1.  Master_host 指的是 主服务器的地址。

2. Master_user 指的是主服务器上用来复制的用户。  从服务器会用此账号来登录主服务。进行复制。

3. Master_log_file 就是前面提到的, 主服务器上的日志文件名.

4. Read_Master_log_pos 就是前面提到的主服务器的日志记录位置, 从服务器根据这两个条件来选择复制的文件和位置。

5. Slave_IO_Running:  指的就是从服务器上负责读取主服务器的线程工作状态。 从服务器用这个专门的线程链接到主服务器上,并把日志拷贝回来。

6. Slave_SQL_Running: 指的就是专门执行sql的线程。 它负责把复制回来的Relaylog执行到自己的数据库中。 这两个参数必须都为Yes 才表明复制在正常工作。

 

其他的参数之后再介绍。

 

 

二, mysql 双机热备实战

了解了上面的原理之后, 我们来实战。 这里有两个重点, 要想同步数据库状态, 需要相同的初态,然后配置同步才有意义。 当然你可以不要初态,这是你的自由。 我们这里从头开始配置一遍。

 

image

 

我们先以A服务器为起点,  配置它的数据库同步到B。  这就是主-从复制了。 之后再反过来做一次,就可以互相备份了。

 

1, 第一步,

在A上面创建专门用于备份的 用户:

 

image

grant replication slave on *.* to 'repl_user'@'192.***.***.***' identified by 'hj34$%&mnkb';

 

上面把ip地址换成B机器的ip地址。 只允许B登录。安全。

用户名为: repl_user

密码为: hj34$********nkb

这个等会在B上面要用。

 

2. 开启主服务器的 binarylog。

很多服务器是默认开启的,我们这里检查一下:

打开 /etc/my.cnf

 

image

 

我来解释一下红框中的配置:

前面三行, 你可能已经有了。

binlog-do-db 用来表示,只把哪些数据库的改动记录到binary日志中。 可以写上关注hello数据库。 但是我把它注释掉了。 只是展示一下。 可以写多行,表示关注多个数据库。

binlog-ignore-db 表示,需要忽略哪些数据库。我这里忽略了其他的4个数据库。

 

后面两个用于在 双主(多主循环)互相备份。 因为每台数据库服务器都可能在同一个表中插入数据,如果表有一个自动增长的主键,那么就会在多服务器上出现主键冲突。  解决这个问题的办法就是让每个数据库的自增主键不连续。  上图说是, 我假设需要将来可能需要10台服务器做备份, 所以auto-increment-increment 设为10.   而 auto-increment-offset=1 表示这台服务器的序号。 从1开始, 不超过auto-increment-increment。

这样做之后, 我在这台服务器上插入的第一个id就是 1, 第二行的id就是 11了, 而不是2.

(同理,在第二台服务器上插入的第一个id就是2, 第二行就是12, 这个后面再介绍) 这样就不会出现主键冲突了。 后面我们会演示这个id的效果。

 

3.  获取主服务器状态, 和同步初态。

假设我现在有这些数据库在A上面。

如果你是全新安装的, 那么不需要同步初态,直接跳过这一步,到后面直接查看主服务器状态。

这里我们假设有一个 hello 数据库作为初态。

 

image

 

先锁定 hello数据库:

FLUSH TABLES WITH READ LOCK;

image

 

然后导出数据:

我这里只需要导出hello数据库, 如果你有多个数据库作为初态的话, 需要导出所有这些数据库:

 

image

 

然后查看A服务器的binary日志位置:

记住这个文件名和 位置, 等会在从服务器上会用到。

 

image

 

主服务器已经做完了, 可以解除锁定了:

 

image

 

 

4.  设置从服务器 B 需要复制的数据库

打开从服务器 B 的 /etc/my.cnf 文件:

 

image

 

解释一下上面的内容。

server-id 必须保证每个服务器不一样。 这可能和循环同步有关。 防止进入死循环。

replicate-do-db 可以指定需要复制的数据库, 我这里注掉了。 演示一下。

replicate-ignore-db 复制时需要排除的数据库, 我使用了,这个。 除开系统的几个数据库之外,所有的数据库都复制。

relay_log 中继日志的名字。 前面说到了, 复制线程需要先把远程的变化拷贝到这个中继日志中, 在执行。

log-slave-updates 意思是,中继日志执行之后,这些变化是否需要计入自己的binarylog。 当你的B服务器需要作为另外一个服务器的主服务器的时候需要打开。  就是双主互相备份,或者多主循环备份。 我们这里需要, 所以打开。

 

保存, 重启mysql。

 

 

5. 导入初态, 开始同步。

把刚才从A服务器上导出的 hello.sql 导入到 B的hello数据库中, 如果B现在没有hello数据库,请先创建一个, 然后再导入:

创建数据库:

create database hello default charset utf8;

把hello.sql 上传到B上, 然后导入:

image

 

如果你刚才导出了多个数据库, 需要把他们都一一上传导入。

 

开启同步, 在B服务器上执行:

 CHANGE MASTER TO 
       MASTER_HOST='192.***.***.***', 
       MASTER_USER='repl_user', 
       MASTER_PASSWORD='hj3****', 
       MASTER_LOG_FILE='mysql-bin.000004', 
       MASTER_LOG_POS=7145;

image

 

上面几个参数我就不解释了。 前面说过了。

 

重启mysql,  然后查看slave线程开启了没:

 

image

 

注意图中的红框, 两个都是Yes, 说明开启成功。

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

如果其中一个是No, 那就说明不成功。需要查看mysql的错误日志。 我在第一次做的时候就遇到这个问题。有时候密码填错了, 有时候防火墙的3306没有打开。ip地址不对,等等。 都会导致失败。

 

我们看错误日志: mysql的错误日志一般在:

 

image

文件名应该是你的机器名, 我这里叫做host1.err 你换成你自己的。

 

到这里主-从复制已经打开了。 我们先来实验一下。

我们在A的数据库里面去 添加数据:

 

image

我在A的 hello数据库的test表中 连续插入了3条数据,  注意看他们的自增长id, 分别是1,11,21.  知道这是为什么吗。 前面已经说过了,不懂再回去看。

 

我们去看一下B数据库有没有这三条数据:

 

打开B的数据库:

image

发现已经在这了。 这里效果不直观。

 

此时不要在B中修改数据。 我们接着配置从B到A的复制。  如果你只需要主从复制的话, 到这里就结束了。后面可以不看了。 所有A中的修改都能自动同步到B, 但是对B的修改却不能同步到A。 因为是单向的。 如果需要双向同步的话,需要再做一次从B到A的复制。

 

基本跟上面一样:我们简单一点介绍:

 

1. 在B中创建用户;

image

 

2. 打开 /etc/my.cnf , 开启B的binarylog:

image

注意红框中所新添加的部分。

 

3. 我们不需要导出B的初态了,因为它刚刚才从A导过来。  直接记住它的master日志状态:

 

image

记住这两个数值,等会在A上面要用。

B服务器就设置完了。

 

4. 登录到A 服务器。 开启中继:

 

image

注意框中心添加的部分, 不解释了。

 

5. 启动同步:

image

上面的ip地址是B的ip地址, 因为A把B当做master了。 不解释了。

 

然后重启mysql服务。

然后查看,slave状态是否正常:

 

image

图中出现了两个No。

Slave_IO_Running: No

Slave_SQL_Running: No

说明slave没有成功, 即,从B到A的同步没有成功。 我们去查看mysql错误日志,前面说过位置:

 

image

 

找到  机器名.err 文件,打开看看:

image

 

看图中的error信息。  说找不到中继日志文件。

这是因为我们在配置A的中继文件时改了中继文件名,但是mysql没有同步。解决办法很简单。

 

image

 

先停掉mysql服务。  找到这三个文件,把他们删掉。 一定要先停掉mysql服务。不然还是不成功。你需要重启一下机器了。 或者手动kill mysqld。

好了, 启动mysql之后。 我们在来检查一下slave状态:

 

image

 

注意图中两个大大的Yes。  哈哈。

 

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

 

证明从B到A的复制也成功了。

 

此时我们去B服务器中插入几条数据试试:

 

image

我在B中插入了两条数据。 注意看他们的id。  不解释。

 

然后我们,登录去A中看看,A数据库变了没。

image

可以看到已经自动同步到A了。

 

至此, AB双主互相热备就介绍完了。

 

原理其实很简单,是不是。

 

理解了这个原理, 多机循环互备就简单了。这里就不再展开了。

 

花了一天时间写这个博客,大家要顶啊。

 

欢迎大家访问我的独立博客:http://blog.byneil.com 多多交流。

 

 

 

参考:

1. mysql-keepalived-实现双主热备读写分离

http://gitsea.com/2013/06/16/mysql-keepalived-%E5%AE%9E%E7%8E%B0%E5%8F%8C%E4%B8%BB%E7%83%AD%E5%A4%87%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB/

 

2. MySQL数据同步【双主热备】http://www.cnblogs.com/zhongweiv/archive/2013/02/01/mysql_replication_circular.html

 

3. Mysql双机热备实现

http://yunnick.iteye.com/blog/1845301

 

4. 高性能Mysql主从架构的复制原理及配置详解http://blog.csdn.net/hguisu/article/details/7325124

 

5.   mysql 基于 master-master 的双机热备配置

简单配置vps,防ddos攻击

防人之心不可无。 网上总有些无聊或者有意的人。不多说了。上干货,配置vps apf防小流量ddos攻击。

对于大流量的ddos攻击, 需要机房的硬件防火墙,vps内部可能也扛不住。

1. 安装 DDoS deflate

DDoS deflate的原理是通过netstat命令找出 发出过量连接的单个IP,并使用iptables防火墙将这些IP进行拒绝。由于iptables防火墙拒绝IP的连接远比从Apache层面上来得高效,因此iptables便成了运行在Apache前端的“过滤器”。同样的,DDoS deflate也可以设置采用APF(高级防火墙)进行IP阻止。

 

wget http://www.inetbase.com/scripts/ddos/install.sh
chmod +x install.sh
./install.sh
主要功能与配置

1、可以设置IP白名单,在 /usr/local/ddos/ignore.ip.list 中设置即可;

2、主要配置文件位于 /usr/local/ddos/ddos.conf ,打开此文件,根据提示进行简单的编辑即可;

3、DDoS deflate可以在阻止某一IP后,隔一段预置的时候自动对其解封;

4、可以在配置文件中设置多长时间检查一次网络连接情况;

5、当阻止IP后,可以设置Email提醒

简单配置一下:

FREQ=1 #检测的频率为1分钟 
NO_OF_CONNECTIONS=100 #当单个IP超过100个连接请求时判定为DDOS

APF_BAN=1 #如果打算使用APF阻止IP,则设置为1(需要预先安装APF);如果使用iptables,则设置为0; 

KILL=1 #是否阻止 

EMAIL_TO="webmaster@firstVM.com" #接收邮件 

BAN_PERIOD=600 #阻止时长,10分钟

 

2. 安装配置apf。

APF(Advanced Policy Firewall)是 Rf-x Networks 出品的Linux环境下的软件防火墙,被大部分Linux服务器管理员所采用,使用iptables的规则,易于理解及使用。

适合对iptables不是很熟悉的人使用,因为它的安装配置比较简单,但是功能还是非常强大的。

脚本安装:

root@linux:/home/zhangy# wget http://www.rfxnetworks.com/downloads/apf-current.tar.gz  
root@linux:/home/zhangy# tar -xvzf apf-current.tar.gz  
root@linux:/home/zhangy# cd apf-9.7-1  
root@linux:/home/zhangy/apf-9.7-1# ./install.sh

ubuntu 可以快速安装:

sudo aptitude install apf-firewall

 

配置:

vi /etc/apf/conf.apf

 

往后翻页,找到:

# Configure inbound (ingress) accepted services. This is an optional
# feature; services and customized entries may be made directly to an ip's
# virtual net file located in the vnet/ directory. Format is comma separated
# and underscore separator for ranges.
#
# Example:
# IG_TCP_CPORTS="21,22,25,53,80,443,110,143,6000_7000"
# IG_UDP_CPORTS="20,21,53,123"
# IG_ICMP_TYPES="3,5,11,0,30,8"

# Common inbound (ingress) TCP ports
IG_TCP_CPORTS="22"

 

默认只有22端口开放。 我们先不管。 访问以下80端口的网站试试。 发现竟然可以访问。 为什么规则没有起作用。

继续查看配置文件。 找啊找。

这一行引起了我的注意:

# Untrusted Network interface(s); all traffic on defined interface will be
# subject to all firewall rules. This should be your internet exposed
# interfaces. Only one interface is accepted for each value.
IFACE_IN="eth0"

突然想到, 会不会是监听端口的问题。

我们知道, 如果是真实服务器或者是 xen虚拟化的vps, 其网卡是 eth*。  例如:

ifconfig

image

但是, 我这台vps是openvz虚拟化的。 它的网卡一般是 vnet* 的。 比如:

 

image

 

于是改上面的配置文件:

# Untrusted Network interface(s); all traffic on defined interface will be
# subject to all firewall rules. This should be your internet exposed
# interfaces. Only one interface is accepted for each value.
IFACE_IN="venet0"

重启 apf:

apf -r

提示说找不到 ip_tables 模块。

ip_tables

apf(4677): {glob} unable to load iptables module (ip_tables), aborting.

image

 

于是搜索:  ubuntu  apf  找到这篇文章

http://davidwinter.me/articles/2011/06/05/install-apf-on-ubuntu-11-04/

 

大致意思是说, 在ubuntu中, iptables默认被编译进了内核, 而不是以模块方式运行的。apf默认是使用模块方式调用iptables。 所以要修改apf的配置:

SET_MONOKERN="1"

 

然后重启 apf

然后看到一长串的日志:

image

 

看样子是成功了。

试一下, 果然80端口不能访问了。

只有22还在。

 

回到配置文件, 我们把端口开放:

vi /etc/apf/conf.apf

找到:

# Configure inbound (ingress) accepted services. This is an optional
# feature; services and customized entries may be made directly to an ip's
# virtual net file located in the vnet/ directory. Format is comma separated
# and underscore separator for ranges.
#
# Example:
# IG_TCP_CPORTS="21,22,25,53,80,443,110,143,6000_7000"
# IG_UDP_CPORTS="20,21,53,123"
# IG_ICMP_TYPES="3,5,11,0,30,8"

# Common inbound (ingress) TCP ports
IG_TCP_CPORTS="22,80,443"

 

保存,重启:  apf –r

 

再访问以下,成功了。

 

最后, 关闭apf的调试模式,正式上线:

找到:

# !!! Do not leave set to (1) !!!
# When set to enabled; 5 minute cronjob is set to stop the firewall. Set
# this off (0) when firewall is determined to be operating as desired.
DEVEL_MODE="1"

 

改成 0:

# !!! Do not leave set to (1) !!!
# When set to enabled; 5 minute cronjob is set to stop the firewall. Set
# this off (0) when firewall is determined to be operating as desired.
DEVEL_MODE="0"

加入到自动启动:

找到这个文件:

/etc/default/apf-firewall

找到:

<code>RUN="no"
改为
</code>
<code>RUN="yes"</code>
<code> </code>

 

欢迎大家访问我的个人独立博客: http://blog.byneil.com

Ubuntu 下完全卸载 apache2

 

Ubuntu自带 apache2 有时候很讨厌。 有时候需要先卸载了再装别的。

 

这里找了一个完全卸载的方法:

 

sudo apt-get autoremove apache2 -y
sudo apt-get remove apache* -y
sudo apt-get --purge remove apache-common -y
sudo apt-get --purge remove apache -y
sudo find /etc -name "*apache*" |xargs  rm -rf 
sudo rm -rf /var/www
sudo rm -rf /etc/libapache2-mod-jk
dpkg -l |grep apache2|awk '{print $2}'|xargs dpkg -P

 

 

have fun.

解决:wordpress无法安装插件,无法安装主题

为了提高本博客的访问速度, 前几天更换了vps, 于是昨天把博客搬家到新的vps上了。

一切看起来还不错。登录后台时发现后台清净了很多。

 

image

也没注意。

今天尝试安装另外一个插件时除了问题。 后台搜索插件:

wordpress无法安装插件,无法安装主题

 

image

第一反应是,文件夹权限不对。

于是, 后台去 chown, chgrp

 

一对权限加到最大。

 

最后发现,新站点php运行在安全模式下, 想到可能是安全模式权限不够, 于是关闭安全模式,问题解决了。

 

这个插件可在后台直接更改 safemode。

不用去修改php配置。

 

http://wordpress.org/plugins/safe-mode/

推荐大家一款便宜vps,kvm架构,128M只要5.99美元一年

更新:

劲爆:512M vps年付只要9.99 美元。

 

推荐大家一款便宜vps,kvm架构,128M只要5.99美元一年。 kvm架构的,你懂的,这是惊世骇俗的白菜价。

昨天刚发现的,顺手抢了两个, 一个做web,一个做mysql, 还不错。 说是过节做活动,不知道现在还有没有。

Micro-128
Self-managed
HDD: 3.0 GB
RAM: 128 MB
CPU: 1x Intel Xeon
BW: 300 GB/mo

 

可选择东西海岸机房。 我选的西海岸洛杉矶机房。

标称128M,  实际使用内存 148M。  良心啊。

image

 

我用的是联通网络你懂的,ping值维持在200上下:

image

支持openvpn,  你知道的。  5.99美元一年的白菜价, 你去买个v-p-n都不止这个价。

单独做站挂个博客绰绰有余。

我顺手抢了两个, 一个跑web, 一个做mysql。

image

点击注册128M kvm vps 5.99美元 一年 。

 

其实还有两款更小的,恐怕只能用来爬墙了。。。 你懂的。

就不推荐大家了。

96M kvm  4.99美元一年。

Micro-96
Self-managed
HDD: 2.0 GB
RAM: 96 MB
CPU: 1x Intel Xeon
BW: 200 GB/mo

image

 

 

64M kvm  3.99 美元 一年

Micro-64
Self-managed
HDD: 1.5 GB
RAM: 64 MB
CPU: 1x Intel Xeon
BW: 100 GB/mo

image

学一点Git–20分钟git快速上手

在Git如日中天的今天,不懂git都不好意思跟人说自己是程序猿。你是不是早就跃跃欲试了,只是苦于没有借口(契机)。 好吧,机会就在今天。 给我20分钟,是的,只要20分钟, 让你快速用上git。

我们废话不多说,直接来干货。

我们将会介绍一下几点:

一, 什么是git

二,使用git的一般开发流程

三,快速安装新建项目。holloword。

开始:

一,什么是git。

阅读本文的前提是你知道或者用过至少一种源代码管理工具,比如:SVN, CVS 或者TFS等等。 你必须知道什么是源代码管理。如果这些都不满足。请直接跳过本文。

了解陌生事物的最好办法,是和已知事物类比。 ---孔子

我们以svn为例。  我们都知道传统的源代码管理都是以服务器为中心的:

image

每个开发者都直接连在中间服务器上, 本地修改,然后commit到svn服务器上。

这种做法看似完美,但是有致命的缺陷:

1. 开发者不能本地跟踪代码版本。 所有的信息都是在服务器上。  你把本地的代码改了很多,但是又不能提交。通常,本地只能缓存一个版本。对于小项目无所谓, 但是项目一复杂,人员多就麻烦了。 通常你本地的代码都全是红色的。自己都不知道今天修改了什么, 有哪些修改是真正应该提交给svn的。

2. 因为第一点,一旦离开服务器, 程序猿将无法正常工作。 因为本地不能跟踪代码版本。  你的(几乎)任何操作都必须连上服务器。比如, show log, blame,show history等等。

3. 中央服务器压力过大。  因为每个人都必须把代码提交到服务器,并且做daily build。

4. 对于大型项目, svn几乎不可用。 例如linux内核项目, 开发者何止几万? 都直接提交给svn服务器的话还不乱套了。

5. 对于个人的私人项目而言(或者对于小公司的项目), 不用版本控制当然不行,但是为了用版本控制而专门假设svn服务器有有点舍不得。

有没有能解决上述几个问题的东东呢?  恩, 答案是肯定的。

Linux内核的作者也遇到了这些问题,于是他决定再一次改变世界, 重写一个可以本地使用的svn。

对, 这就是git。  分布式代码版本管理系统。(说人话 :就是不用服务器的svn)

我们来看git的结构:

image

git没有中央服务器。 你装上git软件之后,你就可以指定本地的文件夹进行版本控制了。你可拔掉网线,然后在本地修改, commit,revert(rollback), branch, restore, show log, blame, history 等等, 全部你之前在svn里面可以用的操作。 简单的说,你就完美了。

 

你可能意识到一个问题了。   就是天下大乱了。

每个人都自顾自的开发,怎么协作呢?  恩,通常git比svn会多出两个操作, 就是 pull 和push。

我们看一个复杂一点的图:

image

开发者之间通过 pull和push操作, 把别人的修改拉过来,或者把自己的修改推给别人。

恩,你可能还是觉得有问题,我们生产 环境中, 以谁的代码为最终版本呢? 

这个问题确实比较棘手,因为,从单纯的技术上将,每个开发者的机器都是对等的。 没有主次之分。

我们还有办法:

技术上不能解决的问题,我们从制度上解决. ---- 孟子

从分布式环境中我们模拟出一个中心来:

image

我们引入Leader这个角色。  他的机器是最终版本。 每个开发者都必须把最终的修改版push给leader。 leader会review然后提交。他就是最终版本。

恩, 我们好像还漏掉一个大问题, 说git,怎么漏掉了github呢。 github是什么。

我们知道,如果每个人都本地修改的话,本地可能不安全,(硬盘坏了,笔记本被偷了。。。。)

我们可能需要一个安全的服务器来存储/备份代码。对于开源的项目,可能是需要一个地方分享你的代码,你不可能24小时开着笔记本,让别人从你这pull代码。

于是, 网上所有的源代码托管网站就冒出来了。 github就是这样的。

看这个图, 我只修改了其中一个地方, 就是把leader的机器换成了。 github.com 提供的在线账户。

image

所以没有git和 github没有必然联系。

这里有几个常用的在线托管地址, 有兴趣自己看看:

1. github.com,  大名鼎鼎。 免费,只支持开源项目, 不支持私有项目。

2.  bitbucket.com ,同样大名鼎鼎。 免费, 支持开源项目和私有项目。 免费用户最多5个。项目无限。

3.   git.oschina.net, 国内顶尖托管平台, 我本人正在用的就是这个。  支持开源项目和私有项目。 成员无限, 项目1000个。   使用的是阿里云服务器, 速度极快。  本人推荐5颗星。

 

二, git开发的一般流程。

上面其实已经涉及了使用git的一般结构。 那么生产环境中, git是如何应用的呢。

本人知道的模型如下:

image

 

每个开发者都向自己的项目服务器(leader)提交代码, leader向公司服务器提交。 当然这个leader是可有可无的。如果项目小的话,  开发者可以直接向公司服务器提交。  公司的服务器就是最终版本。  一般公司还会有持续集成CI服务器。  我们可以在公司的源码服务器上设置git的hook。 自动触发CI服务器工作。 这是后话,不多说了。

 

三,  前面的概念弄清楚之后, 上手就容易多了。 我们helloword。

1.   这是git的官网:http://git-scm.com/  去下载windows客户端。

     如果是linux的话, sudo apt-get install gitcore

2.  注意, 官网的客户端都是命令行的。 命令行是高阶用法。不在这里说了。 我们下个gui。

我用的是TortoiseGit。  https://code.google.com/p/tortoisegit/  , 大家恐怕都熟悉svn时代的乌龟爬。上手快。 我们下面的操作都是gui上的。

安装过程不说了。 一路next。 我们跳过。 直接到最后。假设你现在已经安装完成了。

比如我已经有一个工程, helloworld:

image

这是工程文件的内部结构:

image

现在我们想让helloworld用上git怎么做呢, 在工程根目录下,点击鼠标右键。

image

选择 Create repository。

这个选项不要勾上。 稍后我们会解释什么是 Bare。

image

然后就完成了。

image

里面多出了一个 .git目录。 当前的目录(及其所有子目录)已经在git的监视之中了。 但是当前的代码还没有添加到git的跟踪数据库中。  简单的说,git还没有储存任何版本信息。 我们需要进行第一次提交:

git默认你本地会有一个主分支master。

image

我们写一些注释, 并且勾上想要添加到git的文件。 (如果有子目录的话, 它都会显示在这里。)

image

提交完成, close。 这个push按钮,稍后再说。

image

好了,这个时候我们在回到文件夹,看看有什么变化:

image 

现在这些文件就添加进git了。

剩下的你就可以为所欲为了。 想svn一样,自己试试几个命令吧: 修改, difference, commit, revert,

到这你已经入门了。 

最后我们来介绍两个重要的概念。

1. “git目录”,   就是指上图中,项目根目录下生成的 “.git” 文件夹。  用过svn的同学都知道, svn有‘.svn’文件夹。  他们的作用差不多。 这里保存了git的本地数据库资料。就是所有的版本信息。   跟svn不一样的地方就是,git中,只有根目录下有这个目录, 所有的子目录下都没有, 也就是每个工程只有一个.git目录。

2.  “git工作目录”, 其实就是你的工程目录, 比如上图中的工程跟目录:H:\mycode\helloworld\  。  问什么有这个工作目录呢。 就是你工作在这个目录下, 你可以修改编辑里面的文件,最后把修改提交给git目录。  这个共组目录还有一个神奇的地方就是,  你可以创建不同的branch(你默认工作在master下), 当你切换不同的branch时, 你的工作目录(工程目录)里的所有文件都会变成当前branch对应的文件。 这个不展开了。

 

最后再解释上面留下的两个问题:

1. “Bare”  创建Bare的意思是: 你只想要git的数据库(即上图中的 “.git”文件夹。), 而不想要当前的文件。 这通常用在公司的中央服务器上。 它不需要当前项目的实际代码,只需要保留git数据库信息就行了。

2. 在commit之后的对话框中的 push的意思。   正如之前介绍的。 push的意识是把你的修改push给别人(或者给公共服务器)。  commit的意思只是提交到本地的 .git 数据库。 并没有更新别别人。  所有提交完之后, 乌龟很贴心的给我们一个push按钮。 通过它你可以快速把刚刚的修改push给别人,或者给服务器。 

 

总结, 这不是一本完全的git手册,但至少能让你消除git恐惧症,快速入手。

这里是gitbook的中文版: http://gitbook.liuhui998.com/  他是真正的大而全。 为什么最后才说她呢? 因为它就像是一本 牛津大辞典, 全面,权威。  但是对于幼儿园小朋友学英语,就不能一上来就背它吧。  先跟着别人说,上手要紧。   之后有什么不会的,再去查字典。

好了。 就到这。 欢迎大家访问我的个人独立博客: http://blog.byneil.com  欢迎大家多多交流。

后面有时间的话,还想给大家分享一下我对几大源码托管服务器的经验。 希望大家顶啊。。。。

Thinkphp独立分组模式下,每个分组的单独配置文件config.php位置在哪里

我使用的是Thinkphp 3.1.3,  也就是今天的3.1最新版本。 其实官方3.2已经正式发布了, 看了一下,改变比较多,而且不兼容,所以暂时先不升级了。

我配置了三个独立分组:

'APP_GROUP_LIST'=>'Home,Admin,SN',
 'DEFAULT_GROUP'=>'Home',
 'APP_GROUP_MODE'=>1,

我需要对其中一个分组使用单独的config.php

按照官方的文档:http://doc.thinkphp.cn/manual/group_config.html

--------------------------------------------------------------------------------------------------------------------


如果启用了模块分组,则可以在对每个分组单独定义配置文件,分组配置文件位于:
项目配置目录/分组名称/config.php
可以通过如下配置启用分组:
  1. 'APP_GROUP_LIST' => 'Home,Admin', //项目分组设定
  2.  'DEFAULT_GROUP'  => 'Home', //默认分组
现在定义了Home和Admin两个分组,则我们可以定义分组配置文件如下:
Conf/Home/config.php
Conf/Admin/config.php
每个分组的配置文件仅在当前分组有效,分组配置的定义格式和项目配置是一样的。

 

-----------------------------------------------------------------------------------------------------------------

但是,不知道为什么就是不起作用,这问题困扰了我很久。 网上找到的所有答案都是从官方文档拷的,所以也一样。幸好Thinkphp是开源的。没办法,咱只有读代码了。

在Thinkphp/LIb/Core/Dispatcher.class.php 中找到 dispatch() 函数, 再找到大概 163 行,有个注释:

// 加载分组配置文件
 if(is_file($config_path.'config.php'))
     C(include $config_path.'config.php');

这里就是在加载分组的独立配置文件了。

再倒回去10行左右, 找到 "$config_path" 的定义:

// 定义项目基础加载路径
define('BASE_LIB_PATH', (defined('GROUP_NAME') && C('APP_GROUP_MODE')==1) ? APP_PATH.C('APP_GROUP_PATH').'/'.GROUP_NAME.'/' : LIB_PATH);

结合这两个定义,可以知道,官方的文档说的是错的。  独立分组的配置文件正确的位置在:(以Admin分组为例)

Admin/Config/config.php

这个Admin就是你的分组目录, 不是在Config目录下新建的Admin目录。 全路径看起来应该是这样的:

/app/Modules/Admin/Config/config.php

打完收工。