正在浏览 Linux系统管理 里的文章

今天 帮群里一兄弟配了下nagios上的飞信,这个东西 我个人感觉还是很实用的,不过好久没配了,今天配置了一遍,顺便 就把过程记录下来了,供大家学习!!!

一、安装飞信

cd /root/tools
wget http://ebook.elain.org/tools/fetion20101205.tar.gz

安装步骤略,软件包中有
添加要接收报警短信的手机号为飞信好友

/usr/local/fetion/fetion --mobile=137xxxxxxxx --pwd=1111111 --to=138xxxxxxxx --msg-type=1 --msg-utf8="The Fetion test is ok"

注:第一次要输入验证码,生成验证码后,另开一终端把图片下载下来,打开查看,注意区分大小写!!!

二、vi commands.cfg  添加

define command{
command_name notify-host-by-fetion
command_line /usr/local/fetion/fetion --mobile=137xxxxxxxx --pwd=1111111 --to=138xxxxxxxx --msg-type=1 --msg-utf8="** $NOTIFICATIONTYPE$ Host Alert: $HOSTNAME$ is $HOSTSTATE$ **"
}

define command{
command_name notify-service-by-fetion
command_line /usr/local/fetion/fetion --mobile=137xxxxxxxx --pwd=1111111 --to=138xxxxxxxx --msg-type=1 --msg-utf8="**$NOTIFICATIONTYPE$\n\nService: $SERVICEDESC$\nHost: $HOSTALIAS$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\n\nDate/Time: $LONGDATETIME$\n\nAdditional Info:\n\n$SERVICEOUTPUT$ **"
}

继续阅读

一:"'$var'"

这种写法大家无需改变用'括起awk程序的习惯,是老外常用的写法.如:

var="test"
awk 'BEGIN{print "'$var'"}'

这种写法其实际是双括号变为单括号的常量,传递给了awk.

如果var中含空格,为了shell不把空格作为分格符,便应该如下使用:
var="this is a test"
awk 'BEGIN{print "'"$var"'"}'

二:'"$var"'

这种写法与上一种类似.如果变量含空格,则变为'""$var""'较为可靠.

三.把括起awk程序的''变为"",使用"$var"

如:
$var="this is a test"
awk 'BEGIN{print "$var"}"
这是因为在""里$是特殊字符,而在''里$是普通字符.

四:export 变量,使用ENVIRON["var"]形式,

如:
$var="this is a test";export $var
awk 'BEGIN{print ENVIRON["var"]}'

五:当然也可以使用-v选项

如:
$var="this is a test"
awk -vnvar="$var" '{print nvar}'

这样便把系统变量定义成了awk变量.

前言:经我测试在RHEL5 / CentOS5 / FC13都成功了。

首先介绍下一下具体步骤中涉及到的2个频繁的出现的词语:

taviso:作者 Tavis Ormandy 的简称,Google信息安全工程师 个人微博:http://my.opera.com/taviso/blog/ http://twitter.com/taviso

继续阅读

工作中可能会有无聊的黑客在你服务器上转悠,黑客智商都不错,所有离开的时候就会删除history记录。怎么办才能记录下用户的历史记录呢?
原理:将history记录到syslog上面,并实时的传送到了远端的日志集中服务器上。

方法:使用bash4.1的新功能:历史命令保存到syslog!然后使用syslog-ng构建集中型日志服务器收集主机日志。

1、下载bash:

#wget http://ftp.gnu.org/gnu/bash/bash-4.1.tar.gz
#tar zxvf bash-4.1.tar.gz –C /tmp/bash-4.1
#cd /tmp/bash-4.1

2、修改源码

(根据个人需要,我只保留了pid,uid,sid等,参数请看目录下的shell.c中):
文件bashhist.c大约708行的位置开始,修改成以下一段:

syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY: PID=%d PPID=%d SID=%d  User=%s CMD=%s", getpid(), getppid(), getsid(getpid()),  current_user.user_name, line);
else
{
strncpy (trunc, line, SYSLOG_MAXLEN);
trunc[SYSLOG_MAXLEN - 1] = '\0';
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY (TRUNCATED): PID=%d  PPID=%d SID=%d User=%s CMD=%s", getpid(), getppid(), getsid(getpid()),  current_user.user_name, trunc);
}

注:
ppid:跟踪sh切换后的用户
Sid: 跟踪 su 切换后的用户
第二段代表log长度超过600后使用的语句
修改config-top.h文件

/*#define SYSLOG_HISTORY*/
修改为
#define SYSLOG_HISTORY

编译安装
# ./configure --prefix=/usr/local/bash_4.1 && make && make install
修改用户配置:
将用户的bash换成现在的bash4.1
# vi /etc/passwd
dongwm:x:501:501::/home/dongwm:/usr/local/bash_4.1/bin/bash
这样日志就会记在/var/log/messages
结果类似这样:

Dec 23 17:40:28 server -bash: HISTORY: PID=4089 PPID=4088 SID=4089 User=dongwm CMD=exit
Dec 23 17:41:47 server -bash: HISTORY: PID=4282 PPID=4278 SID=4282 User=root CMD=exit
Dec 23 17:41:53 server -bash: HISTORY: PID=4321 PPID=4317 SID=4321 User=root CMD=ssh java00
Dec 23 17:44:09 server -bash: HISTORY: PID=2152 PPID=2137 SID=2152 User=root CMD=vi Clean_javalog.sh
Dec 23 17:45:16 server -bash: HISTORY: PID=2152 PPID=2137 SID=2152 User=root CMD=sh Clean_javalog.sh
Dec 23 17:45:30 server -bash: HISTORY: PID=2152 PPID=2137 SID=2152 User=root CMD=cat /dev/shm/cleanJavaLog.log
Dec 23 17:46:08 server -bash: HISTORY: PID=2152 PPID=2137 SID=2152 User=root CMD=vi Clean_javalog.sh
Dec 23 17:48:54 server -bash: HISTORY: PID=2152 PPID=2137 SID=2152 User=root CMD=cat Clean_javalog.sh

......

在整个环境布置了记录功能,就能方便的查出来谁-在何时,用什么账号,做了什么操作...

3、主机syslog配置(添加日志服务器的地址)

# vi /etc/syslog.conf

在最后添加一列:
*.* @server.dongwm.com

4、搭建日志服务器

请参看:http://wenku.baidu.com/view/c3bb49c58bd63186bcebbc7a.html

下图是EventLog收集到的bash历史记录信息
Screenshot.png

  除了使用history命令查看历史命令外,Linux系统还提供了非常灵活的Shell历史命令调用方法,我们可以在Shell命令提示符或者Shell脚本中使用它们:
  !!    前一条命令;
  !:0    不带参数的前一条命令名;
  !^    前一条命令的第一个参数;
  !:n    前一条命令的第n个参数;
  !$     前一条命令的最后一个参数;
  !*     前一条命令的所有参数,命令名除外;
  !n     第n条命令;
  !-n    倒数第n条命令;
  !str    最近一条以str开头的命令;
  !?str    最近一条包含str的命令;
  ^a^b  将上一条命令名中的a替换为b;
  !:gs/a/b 将上一条命令的所有a替换为b(包含命令名和参数)。

默认编译安装vim7.2后打开含有中文字符的文件会显示乱码,google了一圈,大多都是说在配置文件中添加下面的几行就可以解决问题:
set encoding=utf-8
set fileencoding=utf-8
但我设置了之后仍然没有解决问题,而且系统中有一个7.0版本的他们使用的是同一个配置文件,7.0版本的就没有问题,7.2版本死活认不了中文,因此怀疑是配置编译选项时肯定有哪些是选项时漏掉了,于是查看configure --help:
...
--enable-workshop       Include Sun Visual Workshop support.
--disable-netbeans      Disable NetBeans integration support.
--enable-sniff          Include Sniff interface.
--enable-multibyte      Include multibyte editing support.
--enable-hangulinput    Include Hangul input support.
--enable-xim            Include XIM input support.
--enable-fontset        Include X fontset output support.
...

选项有很多,只有一项引起了我的注意,看来就是他了,启用多字节编辑支持!重新配置编译选项
$./configure --enable-multibyte
$ make && sudo make install

查看安装后的版本信息
$ vim --version
VIM - Vi IMproved 7.2 (2008 Aug 9, compiled Jun  3 2010 15:09:59)
Normal version without GUI.  Features included (+) or not (-):
... -mouse_sysmouse +mouse_xterm +multi_byte
+multi_lang -mzscheme -netbeans_intg -osfiletype +path_extr...
system vimrc file: "$VIM/vimrc"
user vimrc file: "$HOME/.vimrc"
user exrc file: "$HOME/.exrc"
fall-back for $VIM: "/usr/local/share/vim"
可以清楚的看到,已经支持多字节。尝试打开含有中文的文件,一切正常。

另外介绍两个vim的命令:

1、设置光标行

:set cursorline

这条命令会在vim的光标所在行上标记为一条横线,如下

还可以修饰一下条横线:

:highlight CursorLine guibg=lightblue ctermbg=lightgray]

2、设置光标列

:set cursorcolumn


这样一来就不怕看错行了。呵呵

说明
1、这些命令都可以写在vim的配置文件中~/.vimrc 或/etc/vimrc(CentOS) /etc/vim/vimrc(Ubuntu)
2、只有在gnome或gvim环境下set cursorcolumn命令才会生效,终端模式无效。

分享一份Vim7.2用户手册中文版 点击下载

原创文章,转载请注明: 转自 http://salogs.com

GNU Screen 是一款免费的终端复用程序,它允许一个用户通过单独的窗口或单独的远程终端会话来访问多个分割的终端会话。这段是引用wikipedia.org的解释,实际上Screen实现的就是在一个会话中再打开多个会话。文字描述的不是很明白,看下面的截图就一清二楚了:

它是如何实现的的,下面介绍操作步骤:

1、远程服务器设置

安装screen:
yum install screen -y    [CentOS/RedHat]
apt-get install screen    [Ubuntu/Debian]

配置screen
vi ~/.screenrc

hardstatus on
hardstatus alwayslastline
startup_message off
termcapinfo xterm ti@:te@
hardstatus string "%{= kG}%-w%{.rW}%n %t%{-}%+w %=%{..G} %H %{..Y} %m/%d %C%a "
screen -t bash1 1
screen -t bash2 2
screen -t bash3 3
screen -t bash4 4

上面的配置基本上就是告诉Scree在xterm的下部显示一个状态栏。并且定义指示器的显示方式。并开启四个子shell,名字分别为bash1~4。

2、连接远程服务器

通过SecureCRT连接
设置

这里设置的是连接到SSH服务器自动运行screen程序,从而调用screen的配置文件,启动4个子bash程序。如果不是每次都有这方面的需求的话,也没有必要设置该项,等到想用的时候在执行screen命令也不迟。另外使用screen启动的会话不会因为session的断开而关闭。有关screen的使用参见:使用 screen 管理你的远程会话

Screen中窗口的控制都是使用快捷键来操作,如下:
Ctrl+a n        下一个窗口
Ctrl+a p        上一个窗口
Ctrl+a [1-4]        跳转到指定编号的窗口
Ctrl+a d        断开会话,并不会关闭

查看当前的screen进程
scren -ls
There is a screen on:
9505.main       (Detached)
1 Socket in /var/run/screen/S-root.
关闭指定的screen
kill -9 9505

Linux下连接
先编写一个脚本:
vi remote_screen

orig=`hostname`
echo -e "\033]2;$1\007"
ssh -t $1 screen -S main -xRR -p $2 -q
echo -e "\033]2;$orig\007"

设置可执行
chmod +x remote_screen
mv remote_screen /usr/local/bin/

使用:
remote_screen destination [window_name]

实例:
remote_screen 192.168.108.110
ctrl+a d可以断开会话回到本地shell,当我想重新连接时再运行一遍上面的命令即可。remote_screen命令支持两个参数第二个参数是连接时打开的窗口,如我第一次连接时默认有四个窗口分别为bash1、bash2、bash3、bash4,我断开后第二次连接可以写成remote_screen 192.168.108.110 bash2 这样的话连接后就直接打开了bash2窗口。

备注:

1、连接到screen后可以使用Ctrl+a ? 的方式查看帮助。
2、断开screen后并不是关闭了screen,可以使用screen -ls 查看当前打开的socket有哪些,使用screen -r pid的方式连接已经存在的socket
3、关闭session后screen的进程还会存在,这样我们在执行一些耗费很长时间的命令时就不必再使用nohup命令了
4、screen -ls 后会显示已经存在的screen socket,使用kill -9 pid的方式关闭socket

参考文章:
http://en.wikipedia.org/wiki/GNU_Screen
http://www.ibm.com/developerworks/cn/linux/l-cn-screen/
http://www.earthinfo.org/an-easy-way-to-use-gnu-screen-over-ssh/

原创文章,转载请注明: 转自 http://salogs.com

转自:http://lifehacker.com

Linux/Mac/Cygwin: 如何在终端中通过一条命了创建一个含有空格的文件夹,并同时切到新创建的文件夹下呢?本文介绍小技巧来完成这个功能。

与其利用一条命令创建一个文件夹,然后再用cd进入到新建的文件夹,到不如用另外一条命了来完成这个目的。下面介绍操作步骤:

将下列内容加到~/.bashrc 文件中:

# mkdir, cd into it
mkcd () {
mkdir -p "$*"
cd "$*"
}

然后使用source ~/.bashrc 使其生效,接下来就可以使用mkcd命令了,如下

mkcd New Folder/New Subfolder

mysql安装后提供了一个perl的脚本:mysql_convert_table_format 它默认情况下可以将某个表或某个数据库的所有表转换为MyISAM的存储引擎,通过修改该脚本可以将默认修改的存储引擎改为我们需要的存储引擎,如Innodb。该脚本使用了DBI和DBD的perl模块,如果系统没有安装的话可以使用yum intall perl-DBI perl-DBD-mysql 命令来安装。本文介绍的不是mysql_convert_table_format工具的使用,而是我自己写的一个shell脚本,也可以完成批量转换表存储引擎的目的,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/bin/bash
 
# File          : convert_storage_engine.sh
# Info          : 批量转换表存储引擎,如果忽略-t参数
#                 则转换指定数据库中的所有表。
# Arg1          : -d dbname
# Arg2          : -t [tables]
# Arg3          : -e engine type (myisam | innodb)
# Author        : Cooper
# Site          : http://salogs.com 
# Version       : 2010.05.10 First Release
 
User=root
Pwd=dbpwd
TmpFile="/dev/shm/table.tmp"
MySQLBin="mysql -u$User -p$Pwd -e "
 
function Usage()
{
 echo "Useage:$0 -d dbname [-t table] -e engine_type"
}
 
# 检查用户输入的参数
if [ $# -eq 0 ] ;then
        Usage
        exit 1
fi
 
# 获得命令行参数值,并作相应处理
while getopts t:d:e:h OPTION
do
        case $OPTION in
        d)
           {    # 检查数据库是否存在
                DBName=$OPTARG
                DBExists=`$MySQLBin "show databases;" | grep $DBName`
                if [ "$DBExists" == "" ];then
                   echo "$DBName database not exists!"
                   exit 1
                fi
           }
           ;;
        t)
           {     # 检查表是否存在
                 TableName=$OPTARG
                 TableExists=`$MySQLBin "use $DBName;show tables" | grep $TableName`
                  if [ "$TableExists" == "" ];then
                      echo "$TableName table not exists!"
                      exit 1
                  fi
             }
             ;;
        e)
             EngineName=`echo $OPTARG | tr A-Z a-z `
             if [ $EngineName != "innodb" ] && [ $EngineName != "myisam" ];then
                Usage
                 exit 1
              fi
              ;;
        \?|h)
              Usage
               exit 0
               ;;
        esac
done
 
# 转换表
if [ "$TableName" != "" ];then
{
    CurrentEngine=`$MySQLBin "use $DBName;show table status like \"$TableName\"\G"\
| grep Engine | awk '{print $2}'|tr A-Z a-z`
    if [ $CurrentEngine == $EngineName ];then
        echo "Current Table $Table is already of type $EngineName;Ignored"
        exit 0
    fi
    $MySQLBin "use $DBName;alter table $TableName engine=$EngineName;"
}
else
{
    $MySQLBin "use $DBName;show tables;" | sed 1d >$TmpFile
    while read Table
    do
        CurrentEngine=`$MySQLBin "use $DBName;show table status like '$Table'\G"\
| grep Engine | awk '{print $2}'| tr A-Z a-z`
        if [ $CurrentEngine == $EngineName ];then
           echo "Current Table $Table is already of type $EngineName;Ignored"
           continue
        fi
        $MySQLBin "use $DBName;alter table $Table engine=$EngineName;"
    done<$TmpFile
}
fi
 
rm -rf $TmpFile

注意:
1、由于Innodb不支持FULLTEXT索引,因此在转换表时要格外注意。
2、不要将系统表mysql转换为Innodb,如果这样做了的话,mysql绝对无法启动,需要使用mysql_install_db 命令重建系统表。
3、修改现网数据库需格外注意,转换表时会对表进行锁定。

原创文章,转载请注明: 转自 http://salogs.com

linux下最大文件描述符的限制有两个方面,一个是用户级的限制,另外一个则是系统级限制。

先介绍如何修改系统级的限制

通常我们通过终端连接到linux系统后执行ulimit -n 命令可以看到本次登录的session其文件描述符的限制,如下:
$ulimit -n
1024

当然可以通过ulimit -SHn 102400 命令来修改该限制,但这个变更只对当前的session有效,当断开连接重新连接后更改就失效了。

如果想永久变更需要修改/etc/security/limits.conf 文件,如下:
vi /etc/security/limits.conf
* hard nofile 102400
* soft nofile 102400

保存退出后重新登录,其最大文件描述符已经被永久更改了。

这只是修改用户级的最大文件描述符限制,也就是说每一个用户登录后执行的程序占用文件描述符的总数不能超过这个限制。

系统级的限制

它是限制所有用户打开文件描述符的总和,可以通过修改内核参数来更改该限制:
sysctl -w fs.file-max=102400

使用sysctl命令更改也是临时的,如果想永久更改需要在/etc/sysctl.conf添加
fs.file-max=102400
保存退出后使用sysctl -p 命令使其生效。

与file-max参数相对应的还有file-nr,这个参数是只读的,可以查看当前文件描述符的使用情况。

下面是摘自kernel document中关于file-max和file-nr参数的说明

file-max & file-nr:

The kernel allocates file handles dynamically, but as yet it doesn't free them again.
内核可以动态的分配文件句柄,但到目前为止是不会释放它们的

The value in file-max denotes the maximum number of file handles that the Linux kernel will allocate. When you get lots of error messages about running out of file handles, you might want to increase this limit.
file-max的值是linux内核可以分配的最大文件句柄数。如果你看到了很多关于打开文件数已经达到了最大值的错误信息,你可以试着增加该值的限制

Historically, the three values in file-nr denoted the number of allocated file handles, the number of allocated but unused file handles, and the maximum number of file handles. Linux 2.6 always reports 0 as the number of free file handles -- this is not an error, it just means that the number of allocated file handles exactly matches the number of used file handles.
在kernel 2.6之前的版本中,file-nr 中的值由三部分组成,分别为:1.已经分配的文件句柄数,2.已经分配单没有使用的文件句柄数,3.最大文件句柄数。但在kernel 2.6版本中第二项的值总为0,这并不是一个错误,它实际上意味着已经分配的文件句柄无一浪费的都已经被使用了

file-max的默认值大概是系统内存的10%(系统内存以kb计算),

参考文章:http://www.mjmwired.net/kernel/Documentation/sysctl/fs.txt

http://www.kernel.org

原创文章,转载请注明: 转自 http://salogs.com