1、应70-persystent-net.rules 含有原mac地址,
需删除后开机会自动重建
rm /etc/udev/rules.d/70-prtsystent-net.rules
2、更改/etc/sysconfig/network-scripts/ifg-eth0中的mac地址
可以删除macaddr行或者改成现在的mac地址
1、应70-persystent-net.rules 含有原mac地址,
需删除后开机会自动重建
rm /etc/udev/rules.d/70-prtsystent-net.rules
2、更改/etc/sysconfig/network-scripts/ifg-eth0中的mac地址
可以删除macaddr行或者改成现在的mac地址
创建虚拟机时需注意三点:


Ubuntu安装好以后,创建用户和root密码,进入系统。
点击虚拟机面板“管理-全局设定”,将网络地址设置为与主机同一个网段:

进入Ubuntu网络设置(点击右上角图标),把Host-Only网卡设为手动获取IP地址,填入主机同网段IP:

重启一下网络,用主机ping一下虚拟机地址进行验证。
必须注意的是,如果主机使用Wifi网络连接,需要在主机的无线网络属性中勾选Internet连接共享,共享的网段为192.168.137.1,上述设置要随之变化。

接下来安装增强功能,点击“设备-安装增强功能”,将自动加载光盘:

打开终端运行autorun.sh:
sudo ./autorun.sh
共享粘贴板中勾选双向:

First of all,更新一下系统:
sudo apt upgrade
安装FTP:
sudo apt-get install vsftpd
设置FTP路径:
sudo mkdir /usr/ftp
新建一个用于FTP的用户,设置密码以及工作目录:
sudo useradd -d /home/ftp -s /bin/bash ftpuser
passwd ftpuser
接下来有两种方法让ftpuser拥有更改ftp目录的权限,选项一:授予ftpuser用户读写ftp目录权限:
setfacl -R -m u:ftpuser:rwx /usr/ftp
选项二:将ftpuser添加到用户组ftp中,赋予用户组权限:
usermod -a -G ftp ftpuser
chown -R :ftp /usr/ftp
chmod -R g+rwx /usr/ftp
chmod g+s /usr/ftp
检查vsftpd.conf配置文件:
cat /etc/vsftpd.conf | grep -v "#" | more
在配置文件结尾加上如下字段:
write_enable=YES
local_root=/usr/ftp
chroot_local_user=YES
chroot_list_enable=YES
重新启动vsftpd服务:
sudo service vsftpd restart
打开Ubuntu自带浏览器尝试访问即可。
接下来安装Oracle JDK,这里以8u131版本为例,在Oracle官网上下载 jdk-8u131-linux-x64.tar解压到/usr/java目录(可通过上一步安装的FTP来将JDK安装文件传输到虚拟机目录):
sudo tar -xzvf jdk-8u131-linux-x64.tar.gz
sudo mkdir /usr/java
sudo mv usr/ftp/jdk1.8.0_131 /usr/java/jdk1.8
重命名为jdk1.8是为了之后配置环境变量方便,编辑.bashrc文件:
sudo gedit ~/.bashrc
在文件末尾加上以下内容:
# Java
JAVA_HOME=/usr/java/jdk1.8
JRE_HOME=$JAVA_HOME/jre
JAVA_BIN=$JAVA_HOME/bin
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export JAVA_HOME JRE_HOME PATH CLASSPATH
让更改立即生效:
source ~/.bashrc
验证一下是否配置成功:
java -version

在默认情况下,Virtualbox是无法读取插到主机的U盘、u盾等USB设备的。但是,Virtualbox官方网站还是提供了解决办法。
那就是安装VirtualBox x.x.xxx Oracle VM VirtualBox Extension Pack 这个扩展包。该包的功能简单地说就是提供了USB2.0设备支持,Virtualbox远程桌面协议、Intel PXE启动支持。
下载地址:https://www.virtualbox.org/wiki/Downloads
使用步骤:
1、下载并且安装
2、当主机为WIN,那么在安装好之后就可以支持USB了,当主机为linux时候,还需要把用户加到vboxusers组里
A.在Ubuntu、Debian、Deepin、Linux Mint里
终端打开:sudo gedit /etc/group
找到这一行:vboxusers:x:126:
添加你的用户名,如你的用户名位kevin,则改成 vboxusers:x:126:kevin 然后保存退出
–
B.在Redhat、Fedora、Centos
su -
vi /etc/group
找到这一行:vboxusers:x:126:
添加你的用户名,如你的用户名位kevin,则改成 vboxusers:x:126:kevin 然后保存退出
保存修改后,重启计算机,打开终端,输入 id 看看用户次要组里是不是有了 vboxusers 呢。
这样打开Virtualbox,启动虚拟系统,分配USB设备就行了。
当你在web.xml中配置了字符编码设置,可是请求url中的中文字符仍然乱码,很可能的原因就是Tomcat的字符编码配置问题,具体的解决办法如下。
如果没有指定字符编码,Servlet规范规定使用”ISO-8859-1″作为默认的编码。
如果是get请求,我们可以通过更改Tomcat目录下,conf/server.xml中的Connector中指定 URIEncoding=”UTF-8″ 参数,具体修改内容如下:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8" />
Post请求需要指定它发送的参数和值的编码。因为大多数客户端并没有设置一个明确的编码,默认采用的是ISO-8859-1。大多数情况下,这并不是我们想要的编码,我们可以使用过滤器来进行控制,Tomcat已经提供了完成这个功能的过滤器的例子或者内置了。请参看:
<!--4.x-->
webapps/examples/WEB-INF/classes/filters/SetCharacterEncodingFilter.java
<!--5.x-->
webapps/servlets-examples/WEB-INF/classes/filters/SetCharacterEncodingFilter.java
webapps/jsp-examples/WEB-INF/classes/filters/SetCharacterEncodingFilter.java
<!--6.x-->
webapps/examples/WEB-INF/classes/filters/SetCharacterEncodingFilter.java
<!--7.x (已经将这个Filter加入Tomcat内置了,具体位置:tomcat目录下的conf/web.xml,直接复制一下代码到你的项目web.xml中)-->
<filter>
<filter-name>setCharacterEncodingFilter</filter-name>
<filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>setCharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
[work@112542000 ~]$ jps
290 Bootstrap
61213 Jps
[work@112542000 ~]$ ps -mp 290 -o THREAD,tid,time | sort -k2 -r | head -n 20
USER %CPU PRI SCNT WCHAN USER SYSTEM TID TIME
work 15.3 - - - - - - 03:11:58
work 1.2 19 - - - - 326 00:15:45
work 0.2 19 - - - - 872 00:03:44
work 0.1 19 - - - - 992 00:01:44
work 0.1 19 - - - - 972 00:01:16
work 0.1 19 - - - - 870 00:01:19
work 0.1 19 - - - - 869 00:01:34
work 0.0 19 - - - - 9993 00:00:00
work 0.0 19 - - - - 997 00:00:06
work 0.0 19 - - - - 9969 00:00:00
work 0.0 19 - - - - 9968 00:00:00
work 0.0 19 - - - - 996 00:00:34
work 0.0 19 - - - - 9960 00:00:00
work 0.0 19 - - - - 995 00:00:00
work 0.0 19 - - - - 9944 00:00:00
work 0.0 19 - - - - 994 00:00:31
work 0.0 19 - - - - 9936 00:00:00
work 0.0 19 - - - - 9934 00:00:26
work 0.0 19 - - - - 9933 00:00:21
首先,将十进制的326转换成十六进制,可以在线转换:
http://tool.oschina.net/hexconvert
结果等于146
使用jstack查询该线程堆栈:
[work@112542000 ~]$ jstack 290 | grep "0x160" -A 10
"Timer-2955" daemon prio=10 tid=0x00007f39d3ecd000 nid=0x1602 in Object.wait() [0x00007f38fb273000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.util.TimerThread.mainLoop(Timer.java:552)
- locked <0x00000007c2a0fc40> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:505)
"Timer-2954" daemon prio=10 tid=0x00007f392481e000 nid=0x15e4 in Object.wait() [0x00007f38fbe7f000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.util.TimerThread.mainLoop(Timer.java:552)
--
"Timer-2132" daemon prio=10 tid=0x00007f39d367d000 nid=0x1603 in Object.wait() [0x00007f3933f46000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.util.TimerThread.mainLoop(Timer.java:552)
- locked <0x00000007b44ef3c8> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:505)
"Timer-2131" daemon prio=10 tid=0x00007f39d3b61800 nid=0x15e6 in Object.wait() [0x00007f3934d54000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.util.TimerThread.mainLoop(Timer.java:552)
--
"Timer-450" daemon prio=10 tid=0x00007f39d0728800 nid=0x160 in Object.wait() [0x00007f39b1312000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.util.TimerThread.mainLoop(Timer.java:552)
- locked <0x00000007bddf8788> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:505)
"Timer-449" daemon prio=10 tid=0x00007f39ec01f000 nid=0xffc7 in Object.wait() [0x00007f39af5f5000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.util.TimerThread.mainLoop(Timer.java:552)
近期在排查问题时, 使用 tcpdump 抓包发现一个很奇怪的现象, 所有抓到的包都有重复的一份, 使用 wireshark 查看则表现为 tcp out of order, tcp dup ack 以及 tcp retransmission 这三种提示特别多, 如下图所示:

我们在 centos 6 和 centos 7 系统中验证都有这样的问题, 类似情况见 redhat-1260733
下面开始详细介绍该问题的描述及处理细节:
10.0.21.5 - web 主机 - centos6
10.0.21.7 - redis 主机 - centos7
bond 网络结构大致如下:

两台机器的 eth2, eth3 网口分别连接两个交换机, 选择模式 1 进行设置组成了 bond1 网卡. web 主机 eth2 为当前活跃的网卡, redis 主机 eth3 位当前活跃的网卡.
在 bond 模式为 1(active-backup 模式) 的网络环境下, 使用 tcpdump 及选项 -i any 抓取 web 主机上所有网卡的报文, 使用 wireshark 发现所有的接收和发送都有重复的报文, 而对端的 redis 主机则一切正常.出现的现象如上图所示, 使用以下命令进行抓包测试:
tcpdump -S -s 0 -n -n -i any port 6380 -w 6380.pcap
telnet 10.0.21.7 6380
Trying 10.0.21.7...
Connected to 10.0.21.7.
Escape character is '^]'.
^]
telnet> quit
Connection closed.
web 主机上抓到的包类似下面的内容:
11:18:02.056270 IP 10.0.21.5.24399 > 10.0.21.7.6380: Flags [S], seq 3834591311, win 14600, options [mss 1460,sackOK,TS val 4281235630 ecr 0,nop,wscale 8], length 0
11:18:02.056275 IP 10.0.21.5.24399 > 10.0.21.7.6380: Flags [S], seq 3834591311, win 14600, options [mss 1460,sackOK,TS val 4281235630 ecr 0,nop,wscale 8], length 0
11:18:02.056405 IP 10.0.21.7.3302 > 10.0.21.5.24399: Flags [S.], seq 522913168, ack 3834591312, win 14480, options [mss 1460,sackOK,TS val 3589524071 ecr 4281235630,nop,wscale 8], length 0
11:18:02.056405 IP 10.0.21.7.3302 > 10.0.21.5.24399: Flags [S.], seq 522913168, ack 3834591312, win 14480, options [mss 1460,sackOK,TS val 3589524071 ecr 4281235630,nop,wscale 8], length 0
11:18:02.056425 IP 10.0.21.5.24399 > 10.0.21.7.6380: Flags [.], ack 1, win 58, options [nop,nop,TS val 4281235631 ecr 3589524071], length 0
11:18:02.056426 IP 10.0.21.5.24399 > 10.0.21.7.6380: Flags [.], ack 1, win 58, options [nop,nop,TS val 4281235631 ecr 3589524071], length 0
11:18:02.056560 IP 10.0.21.7.3302 > 10.0.21.5.24399: Flags [P.], seq 1:91, ack 1, win 57, options [nop,nop,TS val 3589524071 ecr 4281235631], length 90
11:18:02.056560 IP 10.0.21.7.3302 > 10.0.21.5.24399: Flags [P.], seq 1:91, ack 1, win 57, options [nop,nop,TS val 3589524071 ecr 4281235631], length 90
可以看到几乎每个包都有重复的条目, 包括 tcp 的三次握手及数据传输等. 所以这里就出现了几个问题:
有趣的是在 redis 主机上单独监听 bond1 网卡, 数据报文都是正常的, web 主机上独立监听 bond1 网卡也是正常的, 这说明 redis 主机并没有向 web 主机重复发送报文, 也说明 web 主机没有重复向 redis 主机发送报文.
对于第一个问题, 很遗憾 tcpdump 并没有类似的功能能够显示来源数据对应的网卡, 所以我们难以区别到底是 eth2 还是 bond1 网卡引起了重复报文. 第二个问题则比较奇特, 从抓出的报文来看 wen 主机重复发送请求但是 redis 主机并没有收到, 这说明重复发送可能只是 web 主机内部的原因, 同样重复接收报文可能也是 web 主机的内部原因.
我们从内核文档bonding 找到以下重复报文相关的内容
10. 小节
For the active-backup, balance-tlb and balance-alb modes, the
promiscuous mode setting is propagated only to the active slave.
......
For the active-backup, balance-tlb and balance-alb modes, when
the active slave changes (e.g., due to a link failure), the
promiscuous setting will be propagated to the new active slave.
......
......
13.2 小节:
This is not due to an error in the bonding driver, rather, it
is a side effect of how many switches update their MAC forwarding
tables. Initially, the switch does not associate the MAC address in
the packet with a particular switch port, and so it may send the
traffic to all ports until its MAC forwarding table is updated. Since
the interfaces attached to the bond may occupy multiple ports on a
single switch, when the switch (temporarily) floods the traffic to all
ports, the bond device receives multiple copies of the same packet
(one per slave device).
The duplicated packet behavior is switch dependent, some
switches exhibit this, and some do not. On switches that display this
behavior, it can be induced by clearing the MAC forwarding table (on
most Cisco switches, the privileged command "clear mac address-table
dynamic" will accomplish this).
从这点看, tcpdump 仅将混杂模式传播到当前活动的网卡中, 另外在交换机进行 MAC 地址学习的时候可能会出现这种重复报文的情况, 这种情况还依赖于交换机的功能. 从这点来看内核文档的解释和我们的问题并没有关系.
由此我们继续追查别的方面, 从底向上的分析, 在 web 主机收到报文的时候, 会对整个报文进行解封装, 如下图所示为数据报文的封装和解封装过程:

从右边的解封装过程来看, 主机的 MAC 地址经过交换机的学习后不会再出现上述内核文档的现象, 而且数据经过传输肯定会先传到 web 主机的 eth2 物理网卡上, 而不是我们认为的直接到 bond1 网卡上. 我们参考文章 tcpdump-work-with-bonding-interface 了解到在 centos 5 系统中, 内核接收到数据报文之后会直接将 skb-dev 从 eth2 更新为 bond1, 最后再将报文通过 bond1 网口发送给 ptye_all, 由于这个工作模式, 直接通过 tcpdump -i eth2 是抓取不到任何包的, 因为报文数据不会经过 eth2.
但是在 linux 内核 3.16 之后, 内核作者 torvalds 修改了工作模式, skb->dev 首先为 eth2 物理网卡, 数据先通过 eth2, 经过 rx_handler 进行处理, 最后找到 bond1 网卡, 再将数据发送到 bond1 进行处理. 如下:
bond related process is moved to dev->rx_handler, Just like the bridge or openvswitch.
Packet will first be processed by ptype_all with skb->dev is eth0 and then rx_handler(bond handler for eth0,eth1). if the rx handler return RX_HANDLER_ANOTHER, the packet arrive by ptye_all again with differentskb->dev (bond0).
从这点来看, web 主机接收的数据报文会先经过 eth2, 再经过 bond1, 而发送的报文则会先经过 bond1, 再经过 eth2 网卡. 而 tcpdump 使用 -i any 选项抓包, 则意味着不管接收还是发送都会出现重复的条目. 为了验证此猜测我们同时监听 eth2 和 bond1 网卡:
在两个终端界面输入下面命令:
tcpdump -S -s 0 -n -n -i eth2 port 6380 -w eth2_6380.pcap
tcpdump -S -s 0 -n -n -i eth2 port 6380 -w bond1_6380.pcap
可以看到如下输出:
eth2 抓包的数据
# tcpdump -n -n -r eth2_6380.pcap
reading from file eth2_6380.pcap, link-type EN10MB (Ethernet)
11:40:59.309086 IP 10.0.21.5.42953 > 10.0.21.7.6380: Flags [S], seq 275391682, win 14600, options [mss 1460,sackOK,TS val 70624316 ecr 0,nop,wscale 8], length 0
11:40:59.309122 IP 10.0.21.7.6380 > 10.0.21.5.42953: Flags [S.], seq 969430611, ack 275391683, win 14480, options [mss 1460,sackOK,TS val 3674159462 ecr 70624316,nop,wscale 8], length 0
11:40:59.309137 IP 10.0.21.5.42953 > 10.0.21.7.6380: Flags [.], ack 1, win 58, options [nop,nop,TS val 70624316 ecr 3674159462], length 0
11:41:01.130610 IP 10.0.21.5.42953 > 10.0.21.7.6380: Flags [P.], seq 1:7, ack 1, win 58, options [nop,nop,TS val 70626138 ecr 3674159462], length 6
11:41:01.130643 IP 10.0.21.7.6380 > 10.0.21.5.42953: Flags [.], ack 7, win 57, options [nop,nop,TS val 3674161283 ecr 70626138], length 0
11:41:01.130728 IP 10.0.21.7.6380 > 10.0.21.5.42953: Flags [.], seq 1:1449, ack 7, win 57, options [nop,nop,TS val 3674161283 ecr 70626138], length 1448
11:41:01.130739 IP 10.0.21.5.42953 > 10.0.21.7.6380: Flags [.], ack 1449, win 69, options [nop,nop,TS val 70626138 ecr 3674161283], length 0
11:41:01.130776 IP 10.0.21.7.6380 > 10.0.21.5.42953: Flags [P.], seq 1449:2193, ack 7, win 57, options [nop,nop,TS val 3674161283 ecr 70626138], length 744
11:41:01.130784 IP 10.0.21.5.42953 > 10.0.21.7.6380: Flags [.], ack 2193, win 80, options [nop,nop,TS val 70626138 ecr 3674161283], length 0
11:41:04.453604 IP 10.0.21.5.42953 > 10.0.21.7.6380: Flags [F.], seq 7, ack 2193, win 80, options [nop,nop,TS val 70629461 ecr 3674161283], length 0
11:41:04.453694 IP 10.0.21.7.6380 > 10.0.21.5.42953: Flags [F.], seq 2193, ack 8, win 57, options [nop,nop,TS val 3674164606 ecr 70629461], length 0
11:41:04.453709 IP 10.0.21.5.42953 > 10.0.21.7.6380: Flags [.], ack 2194, win 80, options [nop,nop,TS val 70629461 ecr 3674164606], length 0
bond1 抓包的数据:
# tcpdump -n -n -r bond1_6380.pcap
reading from file bond1_6380.pcap, link-type EN10MB (Ethernet)
11:40:59.309081 IP 10.0.21.5.42953 > 10.0.21.7.6380: Flags [S], seq 275391682, win 14600, options [mss 1460,sackOK,TS val 70624316 ecr 0,nop,wscale 8], length 0
11:40:59.309122 IP 10.0.21.7.6380 > 10.0.21.5.42953: Flags [S.], seq 969430611, ack 275391683, win 14480, options [mss 1460,sackOK,TS val 3674159462 ecr 70624316,nop,wscale 8], length 0
11:40:59.309136 IP 10.0.21.5.42953 > 10.0.21.7.6380: Flags [.], ack 1, win 58, options [nop,nop,TS val 70624316 ecr 3674159462], length 0
11:41:01.130605 IP 10.0.21.5.42953 > 10.0.21.7.6380: Flags [P.], seq 1:7, ack 1, win 58, options [nop,nop,TS val 70626138 ecr 3674159462], length 6
11:41:01.130643 IP 10.0.21.7.6380 > 10.0.21.5.42953: Flags [.], ack 7, win 57, options [nop,nop,TS val 3674161283 ecr 70626138], length 0
11:41:01.130728 IP 10.0.21.7.6380 > 10.0.21.5.42953: Flags [.], seq 1:1449, ack 7, win 57, options [nop,nop,TS val 3674161283 ecr 70626138], length 1448
11:41:01.130737 IP 10.0.21.5.42953 > 10.0.21.7.6380: Flags [.], ack 1449, win 69, options [nop,nop,TS val 70626138 ecr 3674161283], length 0
11:41:01.130776 IP 10.0.21.7.6380 > 10.0.21.5.42953: Flags [P.], seq 1449:2193, ack 7, win 57, options [nop,nop,TS val 3674161283 ecr 70626138], length 744
11:41:01.130782 IP 10.0.21.5.42953 > 10.0.21.7.6380: Flags [.], ack 2193, win 80, options [nop,nop,TS val 70626138 ecr 3674161283], length 0
11:41:04.453600 IP 10.0.21.5.42953 > 10.0.21.7.6380: Flags [F.], seq 7, ack 2193, win 80, options [nop,nop,TS val 70629461 ecr 3674161283], length 0
11:41:04.453694 IP 10.0.21.7.6380 > 10.0.21.5.42953: Flags [F.], seq 2193, ack 8, win 57, options [nop,nop,TS val 3674164606 ecr 70629461], length 0
11:41:04.453707 IP 10.0.21.5.42953 > 10.0.21.7.6380: Flags [.], ack 2194, win 80, options [nop,nop,TS val 70629461 ecr 3674164606], length 0
可以看到, eth2 和 bond1 抓到了同样的报文, 只是时间戳稍有不同, 这是正常的因为 redis 主机网 web 主机发的包的时间戳是固定的, 上面可以看到从 10.0.21.7 到 10.0.21.5 主机的时间戳都不变化, 而 web 主机到 redis 主机的时间戳则有一些不同, 基本都相差几微秒.
由此可以猜测出, tcpdump 使用 -i any 选项会把 eth2 和 bond1 的报文都抓取, 而两个网卡报文的时间戳有特别相近, 所以使用 wireshark 进行查看的时候会出现各种各样的提示. 以上述的截图为例进行说明:
1、tcp out of order
第一条为三次握手的第一个包, 因为是从 web 主机发出去的, 所以第一条应该是 bond1 网卡的 syn 报文, 紧跟的第二条则为 eth2 网卡的 syn 报文, 而且两个条目还相差 5 微秒, 对于 wireshark 而言第二条报文不是期待的 syn + ack, 时间戳也不一样, 所以就提示乱序. 事实上在 tcp 三次握手和四次回收的过程中是不会出现乱序的, 乱序只在传输数据报文的时候发生.
2、tcp Dup Ack
当乱序或丢包发生时,web 会收到一些 seq 号比期望大的包, web 每收到这种包就会 ack 一次期望的值提醒发送方, 于是就产生 Dup Ack, wireshark 则提示 tcp Dup Ack, 截图中则主要由于时间戳乱序引起了该提示.
3、tcp retransmission
正常情况下, 一个包丢失以及没有后续的 Dup Ack 包, 则会进行超时重传操作. 而在本文的示例中, 由于传输的数据包(P 标志)有重复的而且seq, ack 这些都一样所以 wireshark 会直接提示该包为重传的包.
总体来看, 出现重复报文算是虚惊一场, 不是内核的 bug 也不是 tcpdump 的 bug, 而是 bond 的机制需要经过多次转发处理, 这也能解释为什么 redis 主机上的报文都是正常的. 如上所述, 如果在 centos 5 中抓包应该就不会出现本文的问题. 所以出现重复报文只是一种现象, 不会影响本地网卡的流量, 也不会影响业务的交互. 或许 tcpdump 会在将来修复这个不算错误的漏洞, linux 也可能换一种机制来完成数据的传输.
博主我新买的VPS建站没几天,心想应该没人动我的歪主意就一直没太注意服务器安全。今天用iftop查看到有几个IP一直连接中,而我的blog里的流量统计页面访问数量却没有新增,很明显这不是在访问blog。通过netstat -anp 可以查看到这几个IP,尤其有个IP还不断更换端口一直尝试访问我的22端口,能用22端口无非是ssh终端连接。心里一想百分百99%是尝试暴力破解,事不宜迟赶紧封锁。

一查乌克兰的,还不能ping它,也就是说单向访问

通过iftop能实时查看流量连接情况

tail -f /var/log/secure 可以查看ssh登陆失败的信息,证实了193.201.224.199这家伙在尝试暴力破解
利用denyhosts 防止暴力破解ssh
DenyHosts是Python语言写的一个程序,它会分析sshd的日志文件(/var/log/secure),当发现重 复的攻击时就会记录IP到/etc/hosts.deny文件,从而达到自动屏IP的功能。
思路:利用读取到/var/log/secure登陆失败的IP信息,我们可以设定一个规则,如果登陆失败超过多少次,我们把这个IP写到 /etc/hosts.deny中,拒绝访问!
1、先把始终允许的IP填入 /etc/hosts.allow ,因为自己访问超过了次数那就尴尬了。不过一般购买的VPS都有后台可以更改ROOT登陆密码,所以这个步骤也可以不设置。
# vim /etc/hosts.allow
# sshd:IP:allow
2、安装DenyHosts 官方网站为:http://denyhosts.sourceforge.net
# tar -zxvf DenyHosts-2.6.tar.gz
# cd DenyHosts-2.6
# python setup.py install
3、配置
# cd /usr/share/denyhosts/
# cp denyhosts.cfg-dist denyhosts.cfg
# vi denyhosts.cfg
SECURE_LOG = /var/log/secure #要读取安全日志路径,默认的不管它
HOSTS_DENY = /etc/hosts.deny #将阻止IP写入到hosts.deny,默认的不管它
PURGE_DENY = 1d #设定过多久后清除已阻止IP (m=分钟,h=小时,d=天,w=周)
BLOCK_SERVICE = sshd #阻止服务名
DENY_THRESHOLD_INVALID = 5 #允许无效用户登录失败的次数
DENY_THRESHOLD_VALID = 10 #允许普通用户登录失败的次数
DENY_THRESHOLD_ROOT = 3 #允许root登录失败的次数
(上面3个登陆失败的次数建议不要设定太苛刻,以免自己输错了被列入黑名单了)
DENY_THRESHOLD_RESTRICTED = 1 #设定 deny host 写入到该资料夹
WORK_DIR = /usr/local/share/denyhosts/data #将deny的host或ip纪录到Work_dir中
SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS=YES #假如设定为YES,那么已经设为白名单中的IP登陆失败也会被设为可疑,也会被列入黑名单中,设定NO的意思就相反。
HOSTNAME_LOOKUP=YES #如果可以的话记录登陆失败的hostname
LOCK_FILE = /var/lock/subsys/denyhosts #将DenyHOts启动的pid纪录到LOCK_FILE中,已确保服务正确启动,防止同时启动多个服务。
HOSTNAME_LOOKUP=NO #是否做域名反解
ADMIN_EMAIL = #设置管理员邮件地址
DAEMON_LOG = /var/log/denyhosts #自己的日志文件
DAEMON_PURGE = 10m #该项与PURGE_DENY 设置成一样,也是清除hosts.deniedssh 用户的时间。
4、设置启动脚本
# cp daemon-control-dist daemon-control
# chown root daemon-control
# chmod 700 daemon-control
完了之后执行daemon-contron start就可以了。
# ./daemon-control start
如果要使DenyHosts每次重起后自动启动还需做如下设置:
# ln -s /usr/share/denyhosts/daemon-control /etc/init.d/denyhosts
# chkconfig –add denyhosts
# chkconfig denyhosts on
然后就可以启动了:
# service denyhosts start
# ps -ef|grep denyhosts #检查是否启动

# vim /etc/hosts.deny #查看内是否有禁止的IP,有的话说明已经成功了。

默认情况下,ubuntu系统在安装完成之后,不会安装openssh相关的软件包,所有我们在远程ssh登录到ubuntu系统的时候会失败。
本文将会讲述如何来安装openssh相关软件包来解决无法远程ssh登录到ubuntu系统的问题。
1、执行下面的apt-get命令安装openssh相关软件包。
apt-get install openssh*
ubuntutest@ubuntutest:~$ apt-get install openssh*
E: 无法打开锁文件 /var/lib/dpkg/lock - open (13: Permission denied)
E: 无法对状态列表目录加锁(/var/lib/dpkg/),请查看您是否正以 root 用户运行?
ubuntutest@ubuntutest:~$ sudo apt-get install openssh*
[sudo] password for ubuntutest:
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
注意,根据Glob 'openssh*' 选中了 'openssh-known-hosts'
注意,根据Glob 'openssh*' 选中了 'openssh-blacklist-extra'
注意,根据Glob 'openssh*' 选中了 'openssh-blacklist'
注意,根据Glob 'openssh*' 选中了 'openssh-sftp-server'
注意,根据Glob 'openssh*' 选中了 'openssh-server'
注意,根据Glob 'openssh*' 选中了 'openssh-client'
注意,根据Glob 'openssh*' 选中了 'openssh-client-ssh1'
openssh-blacklist 已经是最新版 (0.4.1+nmu1)。
openssh-blacklist-extra 已经是最新版 (0.4.1+nmu1)。
openssh-known-hosts 已经是最新版 (0.6.2-1)。
openssh-client 已经是最新版 (1:7.2p2-4ubuntu2.2)。
openssh-server 已经是最新版 (1:7.2p2-4ubuntu2.2)。
openssh-sftp-server 已经是最新版 (1:7.2p2-4ubuntu2.2)。
openssh-client-ssh1 已经是最新版 (1:7.2p2-4ubuntu2.2)。
升级了 0 个软件包,新安装了 0 个软件包,要卸载 0 个软件包,有 128 个软件包未被升级。
2、查看sshd 服务是否启动,执行下面的命令
ps aux | grep sshd
ubuntutest@ubuntutest:~$ ps aux | grep sshd
root 1129 0.0 0.2 65520 5272 ? Ss 10:23 0:00 /usr/sbin/sshd -D
root 1304 0.0 0.3 95400 7012 ? Ss 10:24 0:00 sshd: root@pts/0
3、使用非root 用户来验证是否能够SSH远程登录到该Ubuntu系统
ubuntutest@ubuntutest:~$ ssh ubuntutest@localhost
The authenticity of host 'localhost (::1)' can't be established.
ECDSA key fingerprint is SHA256:gy+Rueth1RoavXu2zvs230nZUiCSRIcQZvivSDixfn4.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
ubuntutest@localhost's password:
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-62-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
128 个可升级软件包。
62 个安全更新。
Last login: Wed Aug 2 10:11:14 2017
ubuntutest@ubuntutest:~$
昨天我连接 ssh 的时候看到,有 600 多次来自某个阿里云服务器的失败登录,然后赶紧改了密码,顺便再改一下 ssh 的允许端口……万万没想到,网上搜到的大部分教程均不能生效。在找了几个关键信息后得到比较完全的 CentOS 7 SSH 端口修改步骤。
$ vi /etc/ssh/sshd_config
取消 #Port 22 的注释,在下一行添加你需要修改的新端口 Port 2048。(这里不删除 22 端口是为了防止修改后新端口无法访问,造成无法用 ssh 连接服务器。)
Port 22
Port 2048
修改保存 sshd_config 文件后重启 sshd 服务:
$ systemctl restart sshd
退出 ssh 会话后,再用新的端口连接:
$ ssh -p 2048 [email protected]
ssh: connect to host 0.0.0.0 port 2048: Connection refused
好吧,native 了……对于 CentOS 7 这一套修改端口的方法已经不能生效了。
SELinux 全称 Security Enhanced Linux (安全强化 Linux),是 MAC (Mandatory Access Control,强制访问控制系统)的一个实现,目的在于明确的指明某个进程可以访问哪些资源(文件、网络端口等)。
对于 ssh,SELinux 默认只允许 22 端口,我们可以用 SELinux 管理配置工具 semanage,来修改 ssh 可访问的端口。
$ yum provides semanage
$ yum -y install policycoreutils-python
# 为 ssh 添加新的允许端口
$ semanage port -a -t ssh_port_t -p tcp 2048
# 查看当前 SELinux 允许的端口
$ semanage port -l | grep ssh
ssh_port_t tcp 2048, 22
当 SELINUX 配置为禁用状态时,使用 semanage 会报错提示无法读取 policy 文件:
SELinux: Could not downgrade policy file /etc/selinux/targeted/policy/policy.30, searching for an older version.
SELinux: Could not open policy file <= /etc/selinux/targeted/policy/policy.30: No such file or directory
/sbin/load_policy: Can't load policy: No such file or directory
libsemanage.semanage_reload_policy: load_policy returned error code 2. (No such file or directory).
FileNotFoundError: [Errno 2] No such file or directory
修改 /etc/selinux/config 配置,启用 SELinux:
$ vi /etc/selinux/config
SELINUX=permissive
# 重启服务器
$ init 6
# 重启后查看 SELinux 状态
$ sestatus
# if it shows disable, you can run
$ load_policy -qi
$ semanage port -a -t ssh_port_t -p tcp 2048
$ semanage port -l | grep ssh
ssh_port_t tcp 2048, 22
# 重启 ssh 服务
systemctl restart sshd
注:semange 不能禁用 ssh 的 22 端口:
$ semanage port -d -t ssh_port_t -p tcp 22
ValueError: 在策略中定义了端口 tcp/22,无法删除。
$ systemctl enable firewalld
$ systemctl start firewalld
$ systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: active (running) since 二 2016-12-20 02:12:59 CST; 1 day 13h ago
Main PID: 10379 (firewalld)
CGroup: /system.slice/firewalld.service
└─10379 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid
$ firewall-cmd --state
running
$ firewall-cmd --get-default-zone
public
$ firewall-cmd --get-active-zones
public
interfaces: eth0 eth1
若没有激活区域的话,要执行下面的命令。
$ firewall-cmd --set-default-zone=public
$ firewall-cmd --zone=public --add-interface=eth0
success
$ firewall-cmd --zone=public --add-interface=eth1
success
# 以防新端口不生效,先把 22 端口暴露
$ firewall-cmd --permanent --zone=public --add-port=22/tcp
$ firewall-cmd --permanent --zone=public --add-port=2048/tcp
success
# 重载防火墙
$ firewall-cmd --reload
# 查看暴露端口规则
$ firewall-cmd --permanent --list-port
443/tcp 80/tcp 22/tcp 2048/tcp
$ firewall-cmd --zone=public --list-all
public (default, active)
interfaces: eth0 eth1
sources:
services: dhcpv6-client ssh
ports: 443/tcp 80/tcp 22/tcp 2048/tcp
masquerade: no
forward-ports:
icmp-blocks:
rich rules:
退出 ssh 后,尝试连接新端口
$ ssh -p 2048 [email protected]
成功登录的话,就可以做收尾工作了。
$ vi /etc/ssh/sshd_config
#Port 22
Port 2048
$ systemctl restart sshd
# 用 ss 命令检查 ssh 监听的端口,没有 22 证明修改成功
$ ss -tnlp | grep ssh
LISTEN 0 128 *:2048 *:* users:(("sshd",18233,3))
$ firewall-cmd --permanent --zone=public --remove-port=22/tcp
success
$ firewall-cmd --reload
$ firewall-cmd --permanent --list-port
443/tcp 80/tcp 2048/tcp
ssh 取消监听 22 端口,就已经配置好了,防火墙只不过是在 ssh 外多一层访问限制。如果要做的更好还可以将 22 端口的访问流量转向访问者本地:
$ firewall-cmd --permanen --zone=public --add-forward-port=port=22:proto=tcp:toport=22:toaddr=127.0.0.1
# 配置后重载防火墙,用 ssh -p 22 [email protected] 就会访问到自己本地的 22 端口。
若要删除 forward 配置,可以:
$ firewall-cmd --permanen --zone=public --remove-forward-port=port=22:proto=tcp:toport=22:toaddr=127.0.0.1
检验修改 ssh 端口是否成功:
$ ssh -p 22 [email protected]
# 无响应,因为转到了本地的 22 端口
# 若防火墙未 forward 连接,则会回显 "ssh: connect to host {ip} port 22: Connection refused"
$ ssh -p 2048 [email protected]
# 成功 success
服务器一直 ssh 登录正常,突然有段时间发现不能登录了,查看原因
ssh -v user@host
查看过后,发现问题不在客户端上面
首先查看 .ssh 目录 和 authorized_keys 的权限
.ssh 为 700,authorized_keys 为 600,正常
查看日志
tailf /var/log/secure
返回结果
Authentication refused: bad ownership or modes for directory /root
查看 root 文件夹权限
发现文件夹被改成了 777,改回 755 即可正常登录