Living a Simple Life is a Happy Life

有饭吃,自由自在,就非常开心

Netcat Command

| Comments

Netcat能做到的事情太多了,但和tcpdump一个流派,参数多的令人发指,拣常用的几个命令记录一下

场景

Server A: 192.168.100.100

Server B: 192.168.100.101

端口扫描

1
nc -z -v -n 192.168.100.100 21-25
  • 可以运行在TCP或者UDP模式,默认是TCP,-u参数调整为udp.
  • z 参数告诉Netcat使用Zero IO,指的是一旦连接关闭,不进行数据交换
  • v 参数指使用冗余选项
  • n 参数告诉Netcat 不要使用DNS反向查询IP地址的域名

一旦你发现开放的端口,你可以容易的使用Netcat 连接服务抓取他们的banner。

1
nc -v 192.168.100.100 21

消息传送

两台机器间消息传输

SERVER A:

1
nc -l 1234

Netcat 命令在1567端口启动了一个tcp 服务器,所有的标准输出和输入会输出到该端口。输出和输入都在此shell中展示。

SERVER B:

1
nc 192.168.100.100 1234

不管你在机器B上键入什么都会出现在机器A上

文件传输

大部分时间中,我们都在试图通过网络或者其他工具传输文件。有很多种方法,比如FTP,SCP,SMB等等,但是当你只是需要临时或者一次传输文件,真的值得浪费时间来安装配置一个软件到你的机器上嘛。假设,你想要传一个文件file.txt 从A 到B。A或者B都可以作为服务器或者客户端,以下,让A作为服务器,B为客户端。

SERVER A:

1
nc -l 1234 < file.txt

SERVER B:

1
nc -n 192.168.100.100 1234 > file.txt

这里我们创建了一个服务器在A上并且重定向Netcat的输入为文件file.txt,那么当任何成功连接到该端口,Netcat会发送file的文件内容。

在客户端我们重定向输出到file.txt,当B连接到A,A发送文件内容,B保存文件内容到file.txt.

没有必要创建文件源作为Server,我们也可以相反的方法使用。像下面的我们发送文件从B到A,但是服务器创建在A上,这次我们仅需要重定向Netcat的输出并且重定向B的输入文件。

B作为Server

SERVER B:

1
nc -l 1234 > file.txt

SERVER A:

1
nc 192.168.100.101 1234 < file.txt

目录传输

发送一个文件很简单,但是如果我们想要发送多个文件,或者整个目录,一样很简单,只需要使用压缩工具tar,压缩后发送压缩包。

如果你想要通过网络传输一个目录从A到B。

SERVER A:

1
tar -cvf – dir_name | nc -l 1234

SERVER B:

1
nc -n 192.168.159.100 1234 | tar -xvf -

这里在A服务器上,我们创建一个tar归档包并且通过-在控制台重定向它,然后使用管道,重定向给Netcat,Netcat可以通过网络发送它。

在客户端我们下载该压缩包通过Netcat 管道然后打开文件。

如果想要节省带宽传输压缩包,我们可以使用bzip2或者其他工具压缩。

SERVER A:

1
tar -cvf – dir_name| bzip2 -z | nc -l 1234

通过bzip2压缩

SERVER B:

1
nc -n 192.168.100.100 1234 | bzip2 -d |tar -xvf -

使用bzip2解压

加密你通过网络发送的数据

如果你担心你在网络上发送数据的安全,你可以在发送你的数据之前用如mcrypt的工具加密。

SERVER A:

1
nc 192.168.100.101 1234 | mcrypt –flush –bare -F -q -d -m ecb > file.txt

使用mcrypt工具加密数据。

SERVER B:

1
mcrypt –flush –bare -F -q -m ecb < file.txt | nc -l 1234

使用mcrypt工具解密数据。

以上两个命令会提示需要密码,确保两端使用相同的密码。

这里我们是使用mcrypt用来加密,使用其它任意加密工具都可以。

克隆一个设备

如果你已经安装配置一台Linux机器并且需要重复同样的操作对其他的机器,而你不想在重复配置一遍。不在需要重复配置安装的过程,只启动另一台机器的一些引导可以随身碟和克隆你的机器。

克隆Linux PC很简单,假如你的系统在磁盘/dev/sda上

SERVER A:

1
$dd if=/dev/sda | nc -l 1567

SERVER B:

1
$nc -n 192.168.100.100 1567 | dd of=/dev/sda

打开一个shell

没有telnet和ssh的时候,可以使用Netcat创建远程shell。

假设你的Netcat支持 -c -e 参数(默认 Netcat)

SERVER A:

1
$nc -l 1567 -e /bin/bash -i

SERVER B:

1
$nc 192.168.100.100 1567

这里我们已经创建了一个Netcat服务器并且表示当它连接成功时执行/bin/bash

假如Netcat 不支持-c 或者 -e 参数(openbsd Netcat),我们仍然能够创建远程shell

SERVER A:

1
$mkfifo /tmp/tmp_fifo$cat /tmp/tmp_fifo | /bin/sh -i 2>&1 | nc -l 1567 > /tmp/tmp_fifo

这里我们创建了一个fifo文件,然后使用管道命令把这个fifo文件内容定向到shell 2>&1中。是用来重定向标准错误输出和标准输出,然后管道到Netcat 运行的端口1567上。至此,我们已经把Netcat的输出重定向到fifo文件中。

说明:从网络收到的输入写到fifo文件中

  • cat 命令读取fifo文件并且其内容发送给sh命令

  • sh命令进程收到输入并把它写回到Netcat。

  • Netcat 通过网络发送输出到client

至于为什么会成功是因为管道使命令平行执行,fifo文件用来替代正常文件,因为fifo使读取等待而如果是一个普通文件,cat命令会尽快结束并开始读取空文件。

反向shell

反向shell是人曾经在客户端打开的shell。反向shell这样命名是因为不同于其他配置,这里服务器使用的是由客户提供的服务。

服务端

1
$nc -l 1567

在客户端,简单地告诉Netcat在连接完成后,执行shell。

客户端

1
$nc 192.168.100.100 -e /bin/bash

现在,什么是反向shell的特别之处呢

反向shell经常被用来绕过防火墙的限制,如阻止入站连接。例如,我有一个专用IP地址为192.168.100.100,我使用代理服务器连接到外部网络。如果我想从网络外部访问 这台机器如1.2.3.4的shell,那么我会用反向shell用于这一目的。

指定源端口

假设你的防火墙过滤除25端口外其它所有端口,你需要使用-p选项指定源端口。

服务器端

1
$nc -l 1567

客户端

1
$nc 172.31.100.7 1567 -p 25

使用1024以内的端口需要root权限。

该命令将在客户端开启25端口用于通讯,否则将使用随机端口。

指定源地址

假设你的机器有多个地址,希望明确指定使用哪个地址用于外部数据通讯。我们可以在Netcat中使用-s选项指定ip地址。

服务器端

1
$nc -u -l 1567 < file.txt

客户端

1
$nc -u 172.31.100.7 1567 -s 172.31.100.5 > file.txt

该命令将绑定地址172.31.100.5。

参考:

http://os.51cto.com/art/201304/388721.htm

Crontab Eight Comm

| Comments

网上收集,多次踩坑,立此存照

crontab八诫

  • 不要假定cron知道所需要的特殊环境,它其实并不知道。所以你要保证在shelll脚本中提供所有必要的路径和环境变量,除了一些自动设置的全局变量。所以注意如下2点:

    • 脚本中涉及文件路径时写全局路径;
    • 脚本执行要用到java或其他环境变量时,通过source命令引入环境变量,如:

        #!/bin/sh
        source /etc/profile
        export RUN_CONF=/home/xxxx/boss.conf
        /usr/local/jboss-4.0.5/bin/run.sh -c mev &
      
  • 当手动执行脚本OK,但是crontab死活不执行时。这时必须大胆怀疑是环境变量惹的祸,并可以尝试在crontab中直接引入环境变量解决问题。如:

      0 * * * * . /etc/profile;/bin/sh /var/www/java/audit_no_count/bin/restart_audit.sh
    
  • 新创建的cron job,不会马上执行,至少要过2分钟才执行。如果重启cron则马上执行。

  • 每条 JOB 执行完毕之后,系统会自动将输出发送邮件给当前系统用户。日积月累,非常的多,甚至会撑爆整个系统。所以每条 JOB 命令后面进行重定向处理是非常必要的: >/dev/null 2>&1, 前提是对 Job 中的命令需要正常输出已经作了一定的处理, 比如追加到某个特定日志文件。

  • 当crontab突然失效时,可以尝试/etc/init.d/crond restart解决问题。或者查看日志看某个job有没有执行/报错 tail -f /var/log/cron

  • 千万别乱运行 crontab -r。它从Crontab目录(/var/spool/cron)中删除用户的Crontab文件。删除了该用户的所有crontab都没了。

  • 在crontab中%是有特殊含义的,表示换行的意思。如果要用的话必须进行转义 \%,如经常用的date '+%Y%m%d'在crontab里是不会执行的,应该换成 date '+\%Y\%m\%d'

  • 永远要手工验证一下crontab中的命令

装服务器偶得

| Comments

最近工作需要,连续装了不少服务器。虽然做系统真是没什么技术含量的事,但做多了还是有些想法,记录下。

硬件tips

Dell

  • Dell PowerEdge 2950 2U

  • Dell PowerEdge R610 2U

  • Dell PowerEdge R630 1U

  • Dell PowerEdge R710 1U

  • Dell PowerEdge R720xd 1U

对Dell 系列的服务器印象一直很好,皮实耐折腾, R系列的兼容性也很好,开机启动速度也算是凑合。

但是最近发现一个问题,就是R630 系列的做了Raid5之后,分XFS分区,用clonezilla做镜像的时候非常慢。如果要调大xfs的blocksize,又需要重新编译内核,比较麻烦。

HP

  • HP ProLiant DL380 Gen6 2U

  • HP ProLiant DL360 Gen9 1U

网上对惠普 DL360系列的机器评价很好,但我对它印象不佳。

首先说设计,前面板只有一个usb接口,一般做系统的时候,条件简陋点,需要一个USB光驱,一套键鼠,光驱可以插后面,但是键鼠插后面太麻烦了,所以我比较喜欢前面板有两个USB接口的机器。

然后HP 的BIOS 自检极其缓慢,是Dell的1.5倍。很扯。

然后DL360系列,如果安装centos系,自编译内核的话,需要自己编译Raid驱动,这个极其不爽,而且惠普的官网找驱动,真是费力,而且kernel编出来总有种种小毛病。

比较值得赞扬的是 Gen9以后的机器,做Raid的界面做的挺漂亮的。但是极其坑爹的是,BIOS自检过了以后,没有明确提示按F8进Raid,一定要到网上查。而且我觉得HP的BIOS管理引导做的很啰嗦,要进三层才能看到功能。

Lenovo

  • Lenovo System x3550 M5

公司里说进了IBM的服务器,开机一看,打的Lenovo的LOGO,好吧,原来联想已经做到这个程度了。

机器的配置不错,说说吐槽点:

  • 首先自检的速度又慢了一个档次,重启一遍可以买个包子吃了。

  • BIOS 工具又是层层深入,做Raid估计要进入5级菜单才能搞定。

  • 不支持centos5系了,同事打电话问客服,号称没测过centos6.4以下的,真是理直气壮

吐槽

  • 所有的机器做Raid的那套东西大同小异,控制器都是一家的。但是界面包装有好有坏,按靠谱程度排序 HP>DELL>Lenovo

  • 做好机器后,总是需要在前面贴个标签,现在机器越做越小,最直观的感觉就是前面贴个标签都找不到地方了。看人家管理,有把标签挂在上面的,有在LED屏上编号的,都不方便。为什么没有厂商在前面设计一个小卡片槽,专门放标签纸呢,我估计这个小功能肯定会讨得很多人欢心。

  • 我装服务器,到现在为止一个最大的吐槽点,没有见过一家厂商解决过。就是机器自检的时候,很多显示器兼容性不好,会把左边屏幕的输出吃掉一截。最坑爹的是,每家的BIOS输出都是紧靠左边打出来的,往往会有 F2=Setup 前面的 F2被吃掉的情况,他们就不知道把输出居中一点,我只能说这些公司真是僵化了,下一个诺基亚,说不定就是惠普。

  • 最后就是所有的所谓大公司,官网做的都和微软帮助一个style,就是我按照提示一步步点下去,又回到开始了,它还问我”有帮助吗?”,已经吐槽无力了。在我看来,这些所谓的高科技大公司,其实已经比很多传统行业还恐龙了,看看他们数十年如一日的BIOS就知道了。只不过积累在那里,让他们产生自我感觉良好的错觉。这些公司死是早晚的事。

软件tips

centos5 -> centos6 -> centos7

redhat系的的安装界面 一代比一代漂亮,也一代比一代依赖鼠标。

  • centos5不支持鼠标,熟练后完全依赖键盘一路打下去,很方便
  • centos6 界面很朴素,但比较好用,键盘鼠标都能不是很痛苦的搞定
  • centos7 界面比较花哨了,都做到一个安装界面里,鼠标操作很方便,键盘操作很痛苦,我曾经在没有鼠标的环境下,硬是花了半个小时装了个centos7.1U

孰是孰非,让后来人评说。

xfs resize blocksize

  • xfs做文件系统的时候,试图mkfs.xfs -b –size=xxx ,不生效,默认redhat系的page_size设置的就是4K,xfs的blocksize必须不大于这个size,如果要设大,只能重新编译kernel

Linux Profile and Debug Tools of Performance

| Comments

用perf工具统计系统调用

1
perf top

或者统计一段时间内的调用

1
2
perf record -a -g -F 1000 sleep 30
perf report -g

用strace 追踪某个进程的调用

1
strace -c ls

或者attach一个进程

1
strace -c -p pid

查看磁盘调用

1
lsof -p pid

磁盘负载

1
iostat -x 5 -m

整体负载统计

1
vmstat 5 

Linux Cheat Sheet

| Comments

收集linux下需要多次google的命令

编码问题

  • utf16 > utf8
1
iconv -f UTF-16 -t UTF-8 file_name

web开发命令

  • curl post 一个json文件
1
curl -H "Content-Type: application/json"--data @body.json http://localhost:8080/ui/webapp/conf
  • curl post 一个json字符串
1
curl -H "Content-Type: application/json"-d '{"username":"xyz","password":"xyz"}' http://localhost:3000/api/login

系统时间

  • centos6系列修改时区
1
2
3
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
vim /etc/sysconfig/clock
ZONE="Asia/Shanghai"
  • centos7系列修改时区
1
2
timedatectl list-timezones | grep Asia
timedatectl set-timezone Asia/Shanghai
  • 设置系统时间
1
date +"%Y%m%d%H%M%S"

系统状态

  • 查看系统占用句柄数
1
lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr|more

程序

  • mongo导出
1
mongoexport  -u crossflow -p '0701!1523#SH' -authenticationDatabase admin -d bpc -c main_app_datapath -o main_app_datapath.json

shell 处理

  • 获取当前路径
1
export CURRENT_PATH=$(cd "$(dirname "$0")"; pwd)
  • 检查CPU load
1
2
CURRENT_LOAD=`top -b -n 1|grep 'load average'|awk '{print $12}'|sed 's/,//'`
declare -i current_load=${CURRENT_LOAD%.*}
  • find 匹配多个pattern
1
find /usr/lib64 -name '*.so' -o -name '*.so.1'

文本处理

  • 根据某个字段做uniq
1
sort -u -t, -k1 file

Debug Kernel Panic in Centos

| Comments

当你面对一台新机器,出于某些原因(不是闲的慌)不得不自己编译一个内核时,会碰上kernel panic。

kernel panic很让人心烦,启动时的panic更让人烦,没有挂上硬盘,没有任何log的panic尤其让人烦。

提供几个解决问题的瞎搞方法: (以下内容针对于redhat系,但大部分方法是通用的)

判断引起panic的环节

简单描述下启动流程:

1 Power On                                 Maybe Err:Worlds Collides
2 BIOS                                     Maybe Err:Worlds Collides
3 Load Grub From MBR                       Maybe Err:See nothing
4 load Grub and show it                    Maybe Err:Grub loads failed
5 Grub reads menu.list                     Maybe Err:Grub loads failed
6 Grub loads kernel image                  Maybe Err:Grub loads failed
7 kernel mounts root filesystem            Maybe Err:PANIC
8 kernel runs init                         Maybe Err:PANIC
9 init runs scripts to start               Maybe Err:PANIC

首先你要确认下是哪个环节引起的panic,如果你的log打得比较全,一般能根据蛛丝马迹判断是上面那个环节引起的问题。一般panic发生在step7,step8, step9环节当中。

  • step9: 走到这里已经无大碍,无非是/etc/rc.sysinit 之流挂载了不该有的设备,启动了不知道神马的服务,可以直接在启动脚本中打各种log调试

  • step8: 这个就比较棘手,一般是initramfs 解压后执行某些脚本报错,所幸是大部分都是init级别的,一般可以在grub的kernel后面加参数,挂载shell调,也可以直接用工具修改initramfs镜像中的文件,重新打包二分法定位

  • step7: 也比较棘手,一般panic总要怀疑磁盘驱动,我感觉这个是导致panic的大户,另外如果屏幕没有东东输出,估计视频驱动也要鼓捣一番。

下面针对 step7,step8级别的panic提供一些瞎搞手段

在kernel 参数中加入调试开关,关闭ACPI,selinux

1
2
3
4
  title CentOS (2.6.32-358.el6.x86_64)
          root (hd0,0)
          kernel /vmlinuz-2.6.32-358.el6.x86_64 ro root=/dev/mapper/vg_localhost-lv_root rd_NO_LUKS rd_NO_MD rd_LVM_LV=vg_localhost/lv_swap crashkernel=128M LANG=zh_CN.UTF-8 rd_LVM_LV=vg_localhost/lv_root  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM debug selinux=0 acpi=0
          initrd /initramfs-2.6.32-358.el6.x86_64.img

这是考验人品的时候,不管三七二十一,先把最有可能的问题点排除掉。另外redhat系的会在kernel后面加上 rhgb quiet 之类的参数,统统去掉,开机的时候好好盯着屏幕看看,有没有可疑的东东输出。 因为系统可能会在短时间内输出大量log而没有记录,你需要设置一下输出log的速率和暂停时机,更详细的参数可以在这里找到:

https://wiki.archlinux.org/index.php/Boot_debugging

在kernel 参数中加入dracut的调试开关

redhat系后期采用了dracut构建 initrd镜像,关于dracut的手册在这里:

http://people.redhat.com/harald/dracut-rhel6.html#lsinitrd

调试开关在这里:

https://fedoraproject.org/wiki/How_to_debug_Dracut_problems

你可以设定rdshell,在panic之后跳入dracut提供的shell,打dmesg看看log信息。

最后的最后,实在不知道为啥了,而且你很闲,可以考虑启动时加串口设备调试

一些tooltip

  • 编译kernel的时候,make menuconfig,3.10以后的内核支持搜索某个开关后按数字键直接跳到那个开关的设置项中,这个很有用

  • redhat系用dracut构建initrd,配置文件默认在 /usr/share/dracut/ ,如果你懒得改 initramfs,可以直接修改里面的配置文件,然后重新make install即可

  • 有时候你不好确认根文件系统挂载到哪里了,可以参考这里:

http://free-electrons.com/blog/find-root-device/

其它参考资料:

http://www.tuxradar.com/content/how-fix-linux-boot-problems

Tcpdump Commands

| Comments

tcpdump 的抓包保存到文件的命令参数是-w xxx.cap

  • 抓eth1的包
1
tcpdump -i eth1 -w /tmp/xxx.pcap
  • 抓eth1的包,用ip+port的形式显示通信对
1
tcpdump -i eth1 -nn -w /tmp/xxx.pcap
  • 抓 192.168.1.123的包
1
tcpdump -i eth1 host 192.168.1.123 -w /tmp/xxx.cap
  • 抓192.168.1.123的80端口的包
1
tcpdump -i eth1 host 192.168.1.123 and port 80 -w /tmp/xxx.cap
  • 抓192.168.1.123的icmp的包
1
tcpdump -i eth1 host 192.168.1.123 and icmp -w /tmp/xxx.cap
  • 抓192.168.1.123的80端口和110和25以外的其他端口的包
1
tcpdump -i eth1 host 192.168.1.123 and ! port 80 and ! port 25 and ! port 110 -w /tmp/xxx.cap
  • 抓vlan 1的包
1
tcpdump -i eth1 port 80 and vlan 1 -w /tmp/xxx.cap
  • 抓pppoe的密码
1
tcpdump -i eth1 pppoes -w /tmp/xxx.cap
  • 以100m大小分割保存文件, 超过100m另开一个文件
1
tcpdump -i eth1 -w /tmp/xxx.cap  -C 100m
  • 把后两个数据包并到一个数据包merge.pcap
1
mergecap -w merge.pcap 1.pcap 2.pcap
  • 按照radius条件过滤数据包
1
tshark -r 1.pcap radius -w radius.pcap
  • 按照数据包数分割一个大的数据
1
editcap -c 1000000 merge.pcap split01.pcap
  • split pcap
1
editcap -c 100000 in.pcap out.pcap

How to Xargs Separate Parameters

| Comments

做过很多遍了,每次还是得现查,记一下:

echo "'param 1' 'param 2'" | xargs -n1 | xargs -I@ echo \[@\] \[@\]

output:

1
2
[param 1] [param 1]
[param 2] [param 2]

xargs里面替换字符串

ls|xargs -I @  echo "mv @ @.pack"|sed 's/.json.pack.pack/.pack/g'|bash

Python编程实战 - 笔记1

| Comments

这本书讲的挺实在的,设计模式的部分又复习了一遍。另外又学了几个Python3的新decorator。

创建型设计模式

抽象工厂 (Abstract Factory)

  • 名字就用AbstractFactory好了,不要起什么BaseFactory之类的
  • 相关类都放到对应的Factory Class里面,不要暴露给外面了

建造者模式 (Build)

  • 和工厂的区别就是保存了创建对象时各个部分的细节

工厂模式

  • 根据情况实例化对象
  • 还是注意和抽象工厂的区别,抽象工厂是将创建对象的行为抽象出来,而工厂模式则是根据要创建的对象类型实例化

原型模式 (Prototype)

  • 这个模式其实在javascript的根本,不过Python的实现方法还真是五花八门,我说直接用copy就好了嘛

单例模式 (Singleton)

  • 我最中意的一种实现:
1
2
3
4
5
6
7
8
9
10
11
class Borg:
    _shared_state = {}
    def __init__(self):
        self.__dict__ = self._shared_state

class Singleton(Borg):
    def __init__(self, arg):
        Borg.__init__(self)
        self.val = arg
    def __str__(self):
        return self.val

结构型设计

  • 作用就是改装对象,或者把小对象合并为大对象

Adapter

  • 其实就是转接方法

Bridge

  • 把方法抽象出来

Composite

  • Python里面有一种省一点内存的写法,可以直接用CompositeItem和Item两个类来实现,不过我觉得不直观

decorator

  • 几个新的decorator:

    • @functools_wraps : 装饰器工厂

    • @statically_typed : 类型检查

  • 另外@ensure类修饰符可以用来简化设置property的代码

Facade

  • 这个模式其实是天天在做的,就是把接口聚合的好看一点
  • 其实思想可以推广到很多方面,比如Docker,就是LXC的一个Facader,而且做的比较好看,于是大家就都来用了

Flyweight

  • 管理许多小对象的时候用引用
  • Python用__slot__ Attribute来做最方便
  • 里面关于用shelve对象存储class attribute的思路挺实用的

Multiline Comments in Docker File

| Comments

为了减少Image的fs layout数目,Dockerfile中经常会把多个命令集中到一个 RUN 指令下。

多行之后可读性就很差了。

有个比较偏门的写注释的方法:

1
2
3
4
5
6
7
8
9
10
11
RUN mkdir -p /home/build/npm3 && \
    mkdir -p /home/build/smartprobe && \
    mkdir -p /home/build/bpc3 && \
    `#====================================================` \
    `#=============checkout and install rpms==============` \
    svn export xxx && \
    rpm -ivh --force --nodeps *.rpm && \
    `#====================================================` \
    `#=============checkout and install python==============` \
    ... && \

比较实用,推荐之。