RESTful 接口

RESTful 为 Representational State Transfer 的缩写,拆分开这三个单词来就是:

  • Representational - REST resources can be represented in virtually any form, include XML, JSON, or even HTML 表现层,资源的表现形式
  • State - concerned with the state of a resource 状态,指的是互联网上资源的状态
  • Transfer - transferring resource data 转换,服务端/客户端的转换

Put more succinctly, REST is about transferring the state of resources in a representational form that is most appropriate for the client or server from a server to a client (or vice versa).

These HTTP methods are often mapped to CRUD verbs as follows:

  • Create — POST 新建资源,也可用于更新资源
  • Read — GET 获取资源
  • Update — PUT or PATCH 更新资源,PUT时客户端提供修改的完整资源,PATCH 为客户端提供改变的属性
  • Delete — DELETE 删除资源


  1. 每一个URI代表一种资源;
  2. 客户端和服务器之间,传递这种资源的某种表现层;
  3. 客户端通过四个HTTP动词,对服务器端资源进行操作,实现”表现层状态转化”。

看到这里便可以回答:”PUT 和 POST” 的区别了 —- POST 用来新建资源,而 PUT 和 POST 都可以用来更新资源提交更新。

对于一个 HTTP 请求可以分成一下部分:

VERB is one of the HTTP methods like GET, PUT, POST, DELETE, OPTIONS, etc

URI is the URI of the resource on which the operation is going to be performed

HTTP Version is the version of HTTP, generally “HTTP v1.1” .

Request Header contains the metadata as a collection of key-value pairs of headers and their values. These settings contain information about the message and its sender like client type, the formats client supports, format type of the message body, cache settings for the response, and a lot more information.

Request Body is the actual message content. In a RESTful service, that’s where the representations of resources sit in a message.

对于一个 Http Response 可以分成一下部分:

HTTP Version

Response Code

Response Header

Response Body contains the representation if the request was successful



将API版本放入 URI

或者将版本信息放入 HTTP 头信息中。

以下是读 《Oreilly REST API Design Rulebook》 的一些笔记。

A Web API conforming to the REST architectural style is a REST API.



RFC 3986 * defines the generic URI syntax as shown below:

URI = scheme "://" authority "/" path [ "?" query ] [ "#" fragment ]


  • 使用前置的 “/” (forward slash separator) 来表达资源层级,在 URI 结尾不添加 “/”
  • 使用 Hyphens “-” 来增加可读性,不使用 Underscores “_”
  • 使用小写
  • 不使用 File extensions

Resource Archetypes

A REST API 有 4 种不同的资源原型( Resource Archetypes ) : document, collection, store and controller. 下面四种资源类型翻译出来不伦不类,直接原文反而比较容易明白。

  • A document resource is a singular concept that is akin to an object instance or database record. A document’s state representation typically includes both fields with values and links to other related resources.

  • A collection resource is a server-managed directory of resources. 服务端托管资源的目录

  • A store is a client-managed resource repository. 客户端管理的资源

    The example interaction below shows a user (with ID 1234) of a client program using a fictional Soccer REST API to insert a document resource named alonso in his or her store of favorites:

    PUT /users/1234/favorites/alonso
  • A controller resource models a procedural concept. Controller resources are like executable functions, with parameters and return values; inputs and outputs.

URI Path Design 路径设计

  • 单数名词用于 document
  • 复数名词用于 collection
  • 复数名词用于 store
  • 动词或者动词短语用于 Controller 名字
  • Variable path segments may be substituted with identity-based values
  • CRUD 名字不应该在URI中使用,而应该使用 DELETE /users/1234

URI Query Design 参数设计

  • The query component of a URI may be used to filter collections or stores

    比如 GET /users?role=admin

  • 用来分页

    GET /users?pageSize=25&pageStartIndex=50

Interaction Design with HTTP

REST API 使用 HyperText Transfer Protocol , version 1.1 (HTTP/1.1) , 包括:

  • request methods
  • response codes
  • message headers

RFC 2616 defines the Status-Line syntax as shown below:

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

Request Methods


The purpose of GET is to retrieve a representation of a resource’s state. HEAD is used to retrieve the metadata associated with the resource’s state. PUT should be used to add a new resource to a store or update a resource. DELETE removes a resource from its parent. POST should be used to create a new resource within a collection and execute controllers.


  • GET and POST must not be used to tunnel other request methods
  • GET must be used to retrieve a representation of a resource
  • HEAD should be used to retrieve response headers
  • PUT must be used to both insert and update a stored resource
  • POST must be used to create a new resource in a collection
  • POST must be used to execute controllers
  • DELETE must be used to remove a resource from its parent
  • OPTIONS should be used to retrieve metadata that describes a resource’s available interactions

Response Status Codes 返回码

Category Description 分组描述

1xx: Informational Communicates transfer protocol-level information.

2xx: Success Indicates that the client’s request was accepted successfully.

3xx: Redirection Indicates that the client must take some additional action in order to complete their request.

4xx: Client Error This category of error status codes points the finger at clients. 客户端请求错误

5xx: Server Error The server takes responsibility for these error status codes. 服务器内部错误


  • 200 表明成功, response 需携带 response body
  • 201 Create 表示资源创建成功
  • 202 Accepted 用于表示成功开始了异步动作
  • 204 No Content,通常用于 PUT,POST,和 DELETE 请求的response,如果 GET 返回结果为空,通常也用204
  • 301 “Moved Permanently”,通常应该在返回结果 header 中包含 Location 重定向的请求地址
  • 302 (“Found”) should not be used
  • 303 “See Other” refer the client to a different URI
  • 304 Not Modified preserve bandwidth , client already has the most recent version of the representation
  • 307 Temporary Redirect tell clients to resubmit the request to another URI
  • 400 Bad Request may be used to indicate nonspecific failure,客户端请求错误
  • 401 Unauthorized,must be used 客户端无授权,令牌,密码等无验证
  • 403 Forbidden,should be used to forbid access regardless of authorization state
  • 404 Not found,must be used when a client’s URI cannot be mapped to a resource 不存在该记录
  • 405 (“Method Not Allowed”) must be used when the HTTP method is not supported
  • 406 Not Acceptable,must be used when the requested media type cannot be served
  • 409 Conflict should be used to indicate a vialation of resource state
  • 412 Precondition Failed should be used to support conditional operations
  • 415 Unsupported Media Type must be used when the media type of a request’s payload cannot be processed
  • 500 Internal Server Error should be used to indicate API malfunction

Metadata Design

HTTP Headers

  • Content-Type must be used

  • Content-Length should be used, Content-Length header 给出了整个 body bytes 大小,给出他的理由有两个:1. 客户端可以检查是否读取完整的大小 2. 客户端可以通过 HEAD 请求来得知整个body 的大小,而不同下载。

  • Last-Modified should be used in responses

  • ETag should be used in responses ETag是HTTP协议提供的若干机制中的一种Web缓存验证机制,并且允许客户端进行缓存协商。 这就使得缓存变得更加高效,而且节省带宽。 如果资源的内容没有发生改变,Web服务器就不需要发送一个完整的响应。 ETag也可用于乐观并发控制,作为一种防止资源同步更新而相互覆盖的方法。

  • Location must be used to specify the URI of a newly created resource

  • Cache-Control, Expires, and Date response headers should be used to encourage caching

Media Types

Media Type 有如下语法:

type "/" subtype *( ";" parameter )

type 的值可以有: application, audio, image, message, model, multipart, text 和 video.

A typical REST API will most often work with media types that fall under the application type.


A plain text format with no specific content structure or markup. ‡


Content that is formatted using the HyperText Markup Language (HTML). §


An image compression method that was standardized by the Joint Photographic

Experts Group (JPEG). ‖


Content that is structured using the Extensible Markup Language (XML). #


Content that uses the Atom Syndication Format (Atom), which is an XML-based

format that structures data into lists known as feeds. *


Source code written in the JavaScript programming language. †


The JavaScript Object Notation (JSON) text-based format that is often used by

programs to exchange structured data. ‡

Media Type Design

Client developers are encouraged to rely on the self-descriptive features of a REST API.

Representation Design

REST API 通常使用 response message 的 body 来传递资源的状态。 REST APIs 通常使用文本格式来表示资源。

  • JSON should be supported for resource representation

Client Concerns


  • 使用新的 URIs
  • Schemas
  • Entity tags


  • OAuth

CORS(Cross-origin resource sharing 跨域资源共享) should be supported to provide multi-origin read/write access from JavaScript,克服了 AJAX 只能同源使用资源的限制。







CORS 请求默认不发送 Cookie 和 HTTP 认证信息,如果想要把 Cookie 发送到服务器,一方面要服务器同意,指定 Access-Control-Allow-Credentials 为 true。

调试 RESTful 接口

接口调试工具 Postman


2017-01-10 Web , API , RESTful

每天学习一个命令:lscpu 查看 CPU 信息

lscpu 显示 CPU 的架构信息

lscpusysfsproc/cpuinfo 中收集信息。这个命令的输出是规范的可以用来解析,或者给人来阅读。该命令显示的信息包括,CPU 的数量,线程 (thread),核心 (core),Socket 还有 Non-Uniform Memory Access (NUMA) 节点数。

  • Socket 具体是指的主板上 CPU 的插槽数量,一般笔记本只有一个,而服务器可能会有多个。如果有两个插槽,通常称为两路
  • Core 具体是指 CPU 的核心,也就是平常说的几核,比如八核之类
  • thread 是指的每个 Core 的硬件线程数,超线程

举例来说,如果某个服务器”2 路 4 核超线程”,也就是 2 个插槽,4 核心,默认为 2 thread,也就是 242 是 16 逻辑 CPU。对操作系统来说,逻辑 CPU 的数量就是 Socket * Core * Thread

比如下面我的台式机,1 Sockets, 4 Cores,2 Threads,那么就是 4 核 8 线程。


Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    2
Core(s) per socket:    4
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 94
Model name:            Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Stepping:              3
CPU MHz:               1075.117
CPU max MHz:           4000.0000
CPU min MHz:           800.0000
BogoMIPS:              6816.61
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              8192K
NUMA node0 CPU(s):     0-7
Flags:                 fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb invpcid_single intel_pt retpoline kaiser tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt xsaveopt xsavec xgetbv1 dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp

Byte Order

Big endian vs Little endian 大端和小端,对于整型、长整型等数据类型,Big endian 认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节);而 Little endian 则相反,认为第一个字节是最低位字节(按照从低地址到高地址的顺序存放据的低位字节到高位字节)。

一般来说,x86 系列 CPU 都是 little-endian 的字节序,PowerPC 通常是 big-endian,网络字节顺序也是 big-endian 还有的 CPU 能通过跳线来设置 CPU 工作于 Little endian 还是 Big endian 模式。


Linux 有很多命令可以用来查看 cpu 的信息,如果不使用 lscpu 那么可以直接查看 less /proc/cpuinfo 文件。

或者使用 sudo lshw -class processor


sudo dmidecode -t 4 | less


sudo apt install hardinfo
hardinfo | less


sudo apt install cpuid


sudo apt install inxi
inxi -C


2017-01-09 linux , command

每天学习一个命令:tree 生成目录结构

tree 命令,是一个列出树型目录结构的命令。同时也能够统计出目录下的文件数量和目录数量。

生成目录结构的输出,可以是纯 ASCII 字符,也可以是 html

tree -H baseHREF


tree 命令是用来以树的方式 list 目录下的所有文件

tree -s -v --du -T "目录索引 - Kindle 伴侣每周一书(往期)(更新:06 月 05 日)" -I "Z.*|index*" -h -H  ./ -o index.html


  • -s 列出文件或者目录大小
  • -v 按照字母序排序
  • --du 在目录前显示整个目录的大小
  • -T title 用参数后面的文字替换生成的默认标题
  • -I pattern 用该参数来排除一些目录
  • -h 表示打印出可读的文件大小
  • -H 表示打印 HTML
  • -o file.html 表示打印到文件而不是标准输出

得到如下的 Tree 图:

tree directory structure



tree --help
usage: tree [-acdfghilnpqrstuvxACDFQNSUX] [-H baseHREF] [-T title ] [-L level [-R]]
[-P pattern] [-I pattern] [-o filename] [--version] [--help] [--inodes]
[--device] [--noreport] [--nolinks] [--dirsfirst] [--charset charset]
[--filelimit[=]#] [--si] [--timefmt[=]<f>] [<directory list>]
  ------- Listing options -------
  -a            All files are listed. 显示所有文件和目录,默认情况下不打印隐藏文件(以点开始的文件)。
  -d            List directories only. 显示目录名称。
  -l            Follow symbolic links like directories. 如遇到性质为符号连接的目录,直接列出该连接所指向的原始目录。
  -f            Print the full path prefix for each file. 在每个文件或目录之前,显示完整的相对路径名称。
  -x            Stay on current filesystem only. 将范围局限在现行的文件系统中,若指定目录下的某些子目录,其存放于另一个文件系统上,则将该子目录予以排除在寻找范围外。
  -L level      Descend only level directories deep. 目录深度
  -R            Rerun tree when max dir level reached.
  -P pattern    List only those files that match the pattern given. 只显示符合范本样式的文件或目录名称。
  -I pattern    Do not list files that match the given pattern. 不显示符合范本样式的文件或目录名称。
  --noreport    Turn off file/directory count at end of tree listing.
  --charset X   Use charset X for terminal/HTML and indentation line output. 指定字符集
  --filelimit # Do not descend dirs with more than # files in them.
  --timefmt <f> Print and format time according to the format <f>.
  -o filename   Output to file instead of stdout. 输出到文件,而不是直接输出到标准输出设备
  -------- File options ---------
  --du 在目录前显示整个目录的大小。
  -q            Print non-printable characters as '?'. 用"?"号取代控制字符,列出文件和目录名称。
  -N            Print non-printable characters as is. 直接列出文件和目录名称,包括控制字符。
  -Q            Quote filenames with double quotes.
  -p            Print the protections for each file. 列出权限标示。
  -u            Displays file owner or UID number. 列出文件或目录的拥有者名称,没有对应的名称时,则显示用户识别码。
  -g            Displays file group owner or GID number. 列出文件或目录的所属群组名称,没有对应的名称时,则显示群组识别码。
  -s            Print the size in bytes of each file. 列出文件或目录大小。
  -h            Print the size in a more human readable way. 打印出可读的文件大小, M,G
  --si          Like -h, but use in SI units (powers of 1000).
  -D            Print the date of last modification or (-c) status change. 列出文件或目录的更改时间。
  -F            Appends '/', '=', '*', '@', '|' or '>' as per ls -F. 在执行文件,目录,Socket,符号连接,管道名称名称,各自加上"*","/","=","@","|"号。
  --inodes      Print inode number of each file.
  --device      Print device ID number to which each file belongs.
  ------- Sorting options -------
  -v            Sort files alphanumerically by version. 字母序排序
  -r            Sort files in reverse alphanumeric order. 字母序逆序
  -t            Sort files by last modification time. 最后一次修改时间排序
  -c            Sort files by last status change time.
  -U            Leave files unsorted. 不排序
  --dirsfirst   List directories before files (-U disables).
  ------- Graphics options ------
  -i            Don't print indentation lines. 不以阶梯状列出文件或目录名称。
  -A            Print ANSI lines graphic indentation lines.
  -S            Print with ASCII graphics indentation lines.
  -n            Turn colorization off always (-C overrides). 不在文件和目录清单加上色彩。
  -C            Turn colorization on always. 在文件和目录清单加上色彩,便于区分各种类型。
  ------- XML/HTML options -------
  -X            Prints out an XML representation of the tree.
  -H baseHREF   Prints out HTML format with baseHREF as top directory.
  -T string     Replace the default HTML title and H1 header with string.
  --nolinks     Turn off hyperlinks in HTML output.
  ---- Miscellaneous options ----
  --version     Print version and exit.
  --help        Print usage and this help message and exit.


2017-01-06 linux , tree , command

每天学习一个命令:nmap 扫描开放端口

nmap 是一个网络探测和安全审核工具,能够扫描主机开放端口。nmap 全称 network mapper 网络映射器,设计的目标是快速扫描大型网络。

nmap 以原始 IP 报文来检测网络上有哪些主机,主机运行哪些操作系统(包括版本),主机提供哪些服务(应用程序名和版本),主机使用什么类型的报文过滤器 / 防火墙,以及一堆其它功能。虽然 Nmap 通常用于安全审核,许多系统管理员和网络管理员也用它来做一些日常的工作,比如查看整个网络的信息,管理服务升级计划,以及监视主机和服务的运行。

Nmap 输出的是扫描目标的列表,以及每个目标的补充信息,至于是哪些信息则依赖于所使用的选项。 “所感兴趣的端口表格”是其中的关键。结果列出端口号,协议,服务名称和状态。状态可能是 open(开放的),filtered(被过滤的),closed(关闭的),或者 unfiltered(未被过滤的)。

  • Open(开放的)意味着目标机器上的应用程序正在该端口监听连接 / 报文。
  • filtered(被过滤的) 意味着防火墙,过滤器或者其它网络障碍阻止了该端口被访问,Nmap 无法得知 它是 open(开放的) 还是 closed(关闭的)。 
  • closed(关闭的) 端口没有应用程序在它上面监听,但是他们随时可能开放。
  • unfiltered(未被过滤的)当端口对 Nmap 的探测做出响应,但是 Nmap 无法确定它们是关闭还是开放时
如果 Nmap 报告状态组合 open filtered 和 closed filtered 时,那说明 Nmap 无法确定该端口处于两个状态中的哪一个状态。当要求进行版本探测时,端口表也可以包含软件的版本信息。当要求进行 IP 协议扫描时 (-sO),Nmap 提供关于所支持的 IP 协议而不是正在监听的端口的信息。

除了所感兴趣的端口表,Nmap 还能提供关于目标机的进一步信息,包括反向域名,操作系统猜测,设备类型,和 MAC 地址。


    nmap -A -T4


open 开放的

应用程序正在该端口接收 TCP 连接或者 UDP 报文。发现这一点常常是端口扫描的主要目标,安全意识强的人们知道每个开放的端口都是攻击的入口。攻击者或者入侵测试者想要发现开放的端口。而管理员则试图关闭它们或者用防火墙保护它们以免妨碍了合法用户。非安全扫描可能对开放的端口也感兴趣,因为它们显示了网络上那些服务可供使用。

closed 关闭的

关闭的端口对于 Nmap 也是可访问的(它接受 Nmap 的探测报文并作出响应), 但没有应用程序在其上监听。 它们可以显示该 IP 地址上(主机发现,或者 ping 扫描)的主机正在运行 up 也对部分操作系统探测有所帮助。 因为关闭的关口是可访问的,也许过会儿值得再扫描一下,可能一些又开放了。 系统管理员可能会考虑用防火墙封锁这样的端口。 那样他们就会被显示为被过滤的状态,下面讨论。

filtered 被过滤的

由于包过滤阻止探测报文到达端口,Nmap 无法确定该端口是否开放。过滤可能来自专业的防火墙设备,路由器规则 或者主机上的软件防火墙。这样的端口让攻击者感觉很挫折,因为它们几乎不提供 任何信息。有时候它们响应 ICMP 错误消息如类型 3 代码 13 (无法到达目标:通信被管理员禁止),但更普遍的是过滤器只是丢弃探测帧, 不做任何响应。 这迫使 Nmap 重试若干次以访万一探测包是由于网络阻塞丢弃的。 这使得扫描速度明显变慢。

unfiltered 未被过滤的

未被过滤状态意味着端口可访问,但 Nmap 不能确定它是开放还是关闭。 只有用于映射防火墙规则集的 ACK 扫描才会把端口分类到这种状态。 用其它类型的扫描如窗口扫描,SYN 扫描,或者 FIN 扫描来扫描未被过滤的端口可以帮助确定 端口是否开放。

open filtered 开放或者被过滤的

当无法确定端口是开放还是被过滤的状态。开放的端口不响应就是一个例子,没有响应也可能意味着报文过滤器丢弃了探测报文或者它引发的任何响应。因此 Nmap 无法确定该端口是开放的还是被过滤的。UDP,IP 协议,FIN,Null,和 Xmas 扫描可能把端口归入此类。

closed filtered 关闭或者被过滤的

Nmap 不能确定端口是关闭的还是被过滤的。它只可能出现在 IPID Idle 扫描中。

常用端口 Common Ports

端口号从 1 到 65535

  • 小于 1024 的端口号通常和 Linux 和 Unix-Like 系统内置服务关联,通常不单独使用,一般需要 root 才能开启
  • 1024 到 49151 的端口,被认为是 registered.  通常特定的服务可以向 IANA (Internet Assigned Numbers Authority) 来申请使用。 - 在 49152 到 65535 之间的端口不能被注册使用,并且推荐作为私有用途


20: FTP data
21: FTP control port
22: SSH
23: Telnet <= Insecure, not recommended for most uses
25: SMTP
43: WHOIS protocol
53: DNS services
67: DHCP server port
68: DHCP client port
80: HTTP traffic <= Normal web traffic
110: POP3 mail port
113: Ident authentication services on IRC networks
143: IMAP mail port
161: SNMP
194: IRC389: LDAP port
443: HTTPS <= Secure web traffic
587: SMTP <= message submission port
631: CUPS printing daemon port
666: DOOM <= This legacy FPS game actually has its own special port


    less /etc/services 



    sudo netstat -plunt

netstat 命令用来查看本地端口和服务。

使用 Nmap


sudo apt-get update
sudo apt-get install nmap

nmap 的创建者提供了一个测试服务器


-sT    TCP connect() 扫描,这是最基本的 TCP 扫描方式。这种扫描很容易被检测到,在目标主机的日志中会记录大批的连接请求以及错误信息。    
-sS    TCP 同步扫描 (TCP SYN),因为不必全部打开一个 TCP 连接,所以这项技术通常称为半开扫描 (half-open)。这项技术最大的好处是,很少有系统能够把这记入系统日志。不过,你需要 root 权限来定制 SYN 数据包。    
-sF,-sX,-sN    秘密 FIN 数据包扫描、圣诞树 (Xmas Tree)、空 (Null) 扫描模式。这些扫描方式的理论依据是:关闭的端口需要对你的探测包回应 RST 包,而打开的端口必需忽略有问题的包(参考 RFC 793 第 64 页)。    
-sP    ping 扫描,用 ping 方式检查网络上哪些主机正在运行。当主机阻塞 ICMP echo 请求包是 ping 扫描是无效的。nmap 在任何情况下都会进行 ping 扫描,只有目标主机处于运行状态,才会进行后续的扫描。    
-sU    UDP 的数据包进行扫描,如果你想知道在某台主机上提供哪些 UDP(用户数据报协议,RFC768) 服务,可以使用此选项。    
-sA    ACK 扫描,这项高级的扫描方法通常可以用来穿过防火墙。    
-sW    滑动窗口扫描,非常类似于 ACK 的扫描。    
-sR    RPC 扫描,和其它不同的端口扫描方法结合使用。    
-b    FTP 反弹攻击 (bounce attack),连接到防火墙后面的一台 FTP 服务器做代理,接着进行端口扫描。    


-P0    在扫描之前,不 ping 主机。    
-PT    扫描之前,使用 TCP ping 确定哪些主机正在运行。    
-PS    对于 root 用户,这个选项让 nmap 使用 SYN 包而不是 ACK 包来对目标主机进行扫描。    
-PI    设置这个选项,让 nmap 使用真正的 ping(ICMP echo 请求)来扫描目标主机是否正在运行。    
-PB    这是默认的 ping 扫描选项。它使用 ACK(-PT) 和 ICMP(-PI) 两种扫描类型并行扫描。如果防火墙能够过滤其中一种包,使用这种方法,你就能够穿过防火墙。    
-O    这个选项激活对 TCP/IP 指纹特征 (fingerprinting) 的扫描,获得远程主机的标志,也就是操作系统类型。    
-I    打开 nmap 的反向标志扫描功能。    
-f    使用碎片 IP 数据包发送 SYN、FIN、XMAS、NULL。包增加包过滤、入侵检测系统的难度,使其无法知道你的企图。    
-v    冗余模式。强烈推荐使用这个选项,它会给出扫描过程中的详细信息。    
-S <IP>    在一些情况下,nmap 可能无法确定你的源地址 (nmap 会告诉你)。在这种情况使用这个选项给出你的 IP 地址。    
-g port    设置扫描的源端口。一些天真的防火墙和包过滤器的规则集允许源端口为 DNS(53) 或者 FTP-DATA(20) 的包通过和实现连接。显然,如果攻击者把源端口修改为 20 或者 53,就可以摧毁防火墙的防护。    
-oN    把扫描结果重定向到一个可读的文件 logfilename 中。    
-oS    扫描结果输出到标准输出。    
--host_timeout    设置扫描一台主机的时间,以毫秒为单位。默认的情况下,没有超时限制。    
--max_rtt_timeout    设置对每次探测的等待时间,以毫秒为单位。如果超过这个时间限制就重传或者超时。默认值是大约 9000 毫秒。    
--min_rtt_timeout    设置 nmap 对每次探测至少等待你指定的时间,以毫秒为单位。    
-M count    置进行 TCP connect() 扫描时,最多使用多少个套接字进行并行的扫描。 ```  


目标地址可以为 IP 地址,CIRD 地址等。如,    

-iL filename    从 filename 文件中读取扫描的目标。    
-iR    让 nmap 自己随机挑选主机进行扫描。    
-p    端口 这个选项让你选择要进行扫描的端口号的范围。如:-p 20-30,139,60000
-exclude    排除指定主机。    
-excludefile    排除指定文件中的主机。    



nmap -sS -P0 -sV -O [target]

这里的 target 可以是单一 IP, 或主机名,或域名,或子网

-sS TCP SYN 扫描 (又称半开放,或隐身扫描)
-P0 允许你关闭 ICMP pings.
-sV 打开系统版本检测
-O 尝试识别远程操作系统


-A 同时打开操作系统指纹和版本检测
-v 详细输出扫描情况。


sudo nmap -sP


Usage: nmap [Scan Type(s)] [Options] {target specification}
  Can pass hostnames, IP addresses, networks, etc.
  Ex:,,; 10.0-255.0-255.1-254
  -iL <inputfilename>: Input from list of hosts/networks
  -iR <num hosts>: Choose random targets
  --exclude <host1[,host2][,host3],...>: Exclude hosts/networks
  --excludefile <exclude_file>: Exclude list from file
  -sL: List Scan - simply list targets to scan
  -sP: Ping Scan - go no further than determining if host is online
  -P0: Treat all hosts as online -- skip host discovery
  -PS/PA/PU [portlist]: TCP SYN/ACK or UDP discovery probes to given ports
  -PE/PP/PM: ICMP echo, timestamp, and netmask request discovery probes
  -n/-R: Never do DNS resolution/Always resolve [default: sometimes resolve]
  -sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans
  -sN/sF/sX: TCP Null, FIN, and Xmas scans
  --scanflags <flags>: Customize TCP scan flags
  -sI <zombie host[:probeport]>: Idlescan
  -sO: IP protocol scan
  -b <ftp relay host>: FTP bounce scan
  -p <port ranges>: Only scan specified ports
    Ex: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080
  -F: Fast - Scan only the ports listed in the nmap-services file)
  -r: Scan ports consecutively - don't randomize
  -sV: Probe open ports to determine service/version info
  --version-light: Limit to most likely probes for faster identification
  --version-all: Try every single probe for version detection
  --version-trace: Show detailed version scan activity (for debugging)
  -O: Enable OS detection
  --osscan-limit: Limit OS detection to promising targets
  --osscan-guess: Guess OS more aggressively
  -T[0-6]: Set timing template (higher is faster)
  --min-hostgroup/max-hostgroup <msec>: Parallel host scan group sizes
  --min-parallelism/max-parallelism <msec>: Probe parallelization
  --min-rtt-timeout/max-rtt-timeout/initial-rtt-timeout <msec>: Specifies
      probe round trip time.
  --host-timeout <msec>: Give up on target after this long
  --scan-delay/--max-scan-delay <msec>: Adjust delay between probes
  -f; --mtu <val>: fragment packets (optionally w/given MTU)
  -D <decoy1,decoy2[,ME],...>: Cloak a scan with decoys
  -S <IP_Address>: Spoof source address
  -e <iface>: Use specified interface
  -g/--source-port <portnum>: Use given port number
  --data-length <num>: Append random data to sent packets
  --ttl <val>: Set IP time-to-live field
  --spoof-mac <mac address, prefix, or vendor name>: Spoof your MAC address
  -oN/-oX/-oS/-oG <file>: Output scan results in normal, XML, s|<rIpt kIddi3,
     and Grepable format, respectively, to the given filename.
  -oA <basename>: Output in the three major formats at once
  -v: Increase verbosity level (use twice for more effect)
  -d[level]: Set or increase debugging level (Up to 9 is meaningful)
  --packet-trace: Show all packets sent and received
  --iflist: Print host interfaces and routes (for debugging)
  --append-output: Append to rather than clobber specified output files
  --resume <filename>: Resume an aborted scan
  --stylesheet <path/URL>: XSL stylesheet to transform XML output to HTML
  --no-stylesheet: Prevent Nmap from associating XSL stylesheet w/XML output
  -6: Enable IPv6 scanning
  -A: Enables OS detection and Version detection
  --datadir <dirname>: Specify custom Nmap data file location
  --send-eth/--send-ip: Send packets using raw ethernet frames or IP packets
  --privileged: Assume that the user is fully privileged
  -V: Print version number
  -h: Print this help summary page.
  nmap -v -A
  nmap -v -sP
  nmap -v -iR 10000 -P0 -p 80


2017-01-05 linux , nmap , 学习笔记 , port , network

每天学习一个命令:netstat 查看本地监听端口

以”查看本地端口占用情况”为契机学习一下 netstat 命令。在 man netstat 中的介绍,netstat 可以打印网络连接,路由表,接口信息,masquerade 连接,多播信息的工具。

netstat - Print network connections, routing tables, interface statistics, masquerade connections, and multicast memberships


直接运行以下命令可以打印出当前系统上所有开放的端口(包括 TCP,UDP 端口),进程等等信息

sudo netstat -tupln
  • -l will list listening ports 列出所有在监听的服务端口
  • -p will display the process
  • -n will show port numbers instead of names 尽量显示数字
  • -t to show TCP ports
  • -u will show UDP ports


  • -a 显示当前所有连接
  • -r 显示路由信息
  • -e 显示扩展信息
  • -s 按照各个协议进行统计


字段 含义
Proto 连接使用协议,主要有 TCP 和 UDP,TCP 用来可靠传输,一般用来传输网页,下载文件,而 UDP 在可能丢包的情况下提高了速度,通常用在速度优先的游戏或者直播中
Recv-Q 接受队列,等待读取的数据包队列
Send-Q 发送队列,此队列和上面接受队列一般都为 0,如果不是则表示队列中有正在处理
Local Address 本地地址和端口,显示连接的 host 和 ports
Foreign Address 网络地址
State 显示套接口当前状态,TCP 协议定义的状态包括,LISTEN,等待外部电脑连接我们,ESTABLISHED 已经建立通信
PID/Program 当前网络的 PID 和进程名字


  • LISTEN:侦听来自远方的 TCP 端口的连接请求
  • SYN-SENT:再发送连接请求后等待匹配的连接请求(如果有大量这样的状态包,检查是否中招了)
  • SYN-RECEIVED:再收到和发送一个连接请求后等待对方对连接请求的确认(如有大量此状态,估计被 flood 攻击了)
  • ESTABLISHED:代表一个打开的连接
  • FIN-WAIT-1:等待远程 TCP 连接中断请求,或先前的连接中断请求的确认
  • FIN-WAIT-2:从远程 TCP 等待连接中断请求
  • CLOSE-WAIT:等待从本地用户发来的连接中断请求
  • CLOSING:等待远程 TCP 对连接中断的确认
  • LAST-ACK:等待原来的发向远程 TCP 的连接中断请求的确认(不是什么好东西,此项出现,检查是否被攻击)
  • TIME-WAIT:等待足够的时间以确保远程 TCP 接收到连接中断请求的确认
  • CLOSED:没有任何连接状态



-a 选项会列出所有连接

netstat -a

列出所有 tcp 端口

netstat -at

列出 udp 端口

netstat -au

列出处于监听状态的 Sockets

网络服务的后台进程都会打开一个端口,用于监听请求,使用 -l 参数列出正在监听的网络端口

netstat -l

-l 只会显示监听的端口,不会显示连接

只列出所有监听 tcp 的端口

netstat -lt

同理,只监听 udp 的端口

netstat -lu


-p 选项会打印出进程的名字

sudo netstat -p

需要注意 -p 选项使用 root 运行,大部分网络服务都需要 root 运行

持续输出 netstat 信息

netstat -c


-n 选项禁用域名反向解析,打印的结果中将只会有 IP 地址

netstat -ant


除了打印基本的网络信息,netstat 也可以打印路由表

netstat -r


Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
default         UG        0 0          0 eth0       *        U         0 0          0 outline-tun0    *        U         0 0          0 eth0      *          U         0 0          0 docker0      *          U         0 0          0 br-bcb55debff13


  • Destination 列,表示网络包传输的目的地网络地址,最后一位 0,表示任何匹配的地址,比如 则匹配,也能匹配,但是不能匹配 。 default 表示的是,匹配任何地址
  • Gateway 列表示当匹配第一列之后将数据包传送给谁,如果是 * (asterisk) 则表示 send locally 发送给本机
  • Genmask 列,表示子网
  • Flags 列,表示哪一个 flags 应用到当前表,”U“ 表示 Up,当前激活,如果是 G 则表示当前行作为 Gateway
  • MSS 列表示,Maximum Segment Size,MSS 是 TCP 的参数,用来切分网络包。但是如今大部分计算机已经对处理这些包没有任何问题,所以这一列通常是 0,表示 ”no changes“
  • Window 列,TCP 参数
  • irtt 列,表示 Initial Round Trip Time
  • Iface 列,显示匹配之后发送到哪一个网络接口


netstat -i

如果需要更加详细的信息可以添加 -e

netstat -ie

那么此刻打印的内容就和 ifconfig 一样了


netstat -ic


2017-01-04 network , linux , netstat , ports

修复 Linux mint 下 sogou 输入法

记录一下 Linux 下 Sogou 输入法失效的问题,以及解决修复过程。 Linux 真是太难折腾了,一些配置总是太乱,没有文档,没有集中的 Q&A ,导致使用过程非常困难,一些基础设施都很难用。当然如果调教的好,也是能够非常高效的。比如解决了这个基础打字问题之后的这篇文章就是在 Linux Mint 下完成的。


不知道是系统升级还是因为输入法升级,(可在我印象中完全没有做任何干扰到输入法的事情),搜狗输入法 Linux 版,就这么挂掉了,而其他设置一切正常,其他的输入法也都一切正常,但是实在无法用的过来, RIME没有一个可更新的词库,google pinyin 也是词库不全,使用起来总还是不太方便,虽然 sogou 输入法在 Linux 下有些问题所在,但是还是相对来说比较好用的,但是它就这么挂了。


在刚开始的时候以为是 Fcitx 的问题,卸载 sudo apt remove fcitx,重装,登入登出好几回,发现并没有任何用,期间也尝试使用过 iBus,但是实在无法使用。

最后在网上查阅问题的时候,发现 搜狗输入法在系统的 ~/.config 下会有三个配置文件夹,包括

  • SogouPY
  • SogouPY.user
  • sogou-qimpanel


2017-01-03 Linux , Linux Mint , Sogou

Java 查漏补缺之注解



  • 提供信息给编译器:编译器可以利用注解来探测错误和警告信息
  • 编译阶段时的处理:软件工具可以用来利用注解信息来生成代码、Html 文档或者做其它相应处理
  • 运行时的处理:某些注解可以在程序运行的时候接受代码的提取


常用的注解 @Override 等等就略过,如果注解有 annotation type element declarations,可写成:

@SuppressWarnings(value = "unchecked")
void myMethod() { ... }


void myMethod() { ... }

如果没有 annotation type element declarations,括号也能省略。如果遇到

@Author(name = "Jane Doe")
@Author(name = "John Smith")
class MyClass { ... }

这样的形式,这是 Java 8 引入的新的 Repeating Annotations 注解。

注解可以在定义时使用,包括类定义,field 定义,方法定义时。 Java 8 之后,注解也可以用在下面这些情况:

  • 类实例化时

      new @Interned MyObject()
  • 强制类型装换时

      myString = (@NonNull String) str;
  • implements 语句

      class UnmodifiableList<T> implements
              @Readonly List<@Readonly T> { ... }
  • 抛出异常时

      void monitorTemperature() throws
              @Critical TemperatureException { ... }

这种类型的注解叫做 type annotation,更多信息可以在这里 查看。


看上去很像接口,下面是 JDK 中自带的 Override 注解

public @interface Override {


public @interface TimeCost {
    public boolean enabled() default true;

注解的属性也叫做 annotation type element declarations,看起来像方法,但是不是。注解只有 annotation type element declarations,没有方法。注解的 annotation type element declarations 在注解的定义中以“无形参的方法”形式来声明,其方法名定义了该 annotation type element declarations 的名字,其返回值定义了该 annotation type element declarations 的类型。


Java 中有如下元注解 (meta-annotation),可以理解成定义注解的注解。

注解名字 解释
@Target 定义的注解可以用于什么地方,详见 ElementType 枚举
@Retention 在什么级别保存该注解信息,详见 RetentionPolicy 枚举
@Document 将注解包含在 Javadoc 中
@Inherited 允许子类继承父类中的注解
@Repeatable 表示该注解可以在同一个定义地方被多次使用

前四个注解是 Java 5 引入,后 Java 8 引入了 Repeating Annotations.

Repeating Annotations

可重复的注解是 Java 8 引入的内容,为什么需要可重复的注解呢?举个官方文档上的例子,比如说定义了一个定时任务,有两种方式来驱动

@Schedule(dayOfWeek="Fri", hour="23")
public void doPeriodicCleanup() { ... }


public class UnauthorizedAccessException extends SecurityException { ... }

为了实现可重复的注解,在注解定义时需要添加 @Repeatable 元注解

import java.lang.annotation.Repeatable;

public @interface Schedule {
  String dayOfMonth() default "first";
  String dayOfWeek() default "Mon";
  int hour() default 12;

@Repeating 元注解括号中需要定义 container annotation,这个 container annotation 是 Java 编译器生成用来存储可重复注解的。在例子中,container annotation type 就是 Schedules,因此可重复注解 @Shedule 就被保存在 @Schedules 中。

定义 container annotation type 必须要包含一个 value 变量,这个变量是一个包含注解的数组。

public @interface Schedules {
    Schedule[] value();


通过反射获取注解有很多方法,之前的 AnnotatedElement.getAnnotation(Class<T>) 方法维持不变,依然返回一个注解。或者在 JAVA 8 以后,可以通过 AnnotatedElement.getAnnotationsByType(Class<T>) 来一次性获取多个注解。


2017-01-03 java , annotation , interface

每天学习一个命令:iptables Linux 上的防火墙

iptables 命令是 Linux 上常用的防火墙软件,是 netfilter 项目的一部分。可以直接配置,也可以通过许多前端和图形界面配置。这篇文章主要介绍 iptables 的安装,添加规则,清除规则,开放指定端口,屏蔽指定 ip,ip 段,等等基本功能。

iptables/ip6tables - administration tool for IPv4/IPv6 packet filtering and NAT


Ubuntu/Linux Mint 系系统:

sudo apt-get install iptables

iptables 防火墙用于创建过滤规则和 NAT(网络地址转换) 规则,几乎所有 Linux 发行版都能使用。 iptables 的结构 iptables -> Tables -> Chains -> Rules ,简单地,Tables 由 Chains 组成,Chains 又由 Rules 组成。

Table 组成

iptables 具有 Filter,NAT,Mangel,Raw,security 这几种内建表:

Filter 表

Filter 是 iptables 默认表,内建链

  • INPUT 链,处理来自外部的数据
  • OUTPUT 链,处理向外发送的数据
  • FORWARD 链,将数据转发到本机的其他网卡设备



  • PREROUTING 链,处理刚到达本机并在路由转发前的数据包。它会转换数据包中的目标 IP 地址(destination ip address),通常用于 DNAT
  • POSTROUTING 链,处理即将离开本机的数据包,将会转换数据包中的源 IP 地址(source ip address),通常用于 SNAT(source NAT)
  • OUTPUT 链,处理本机产生的数据包

Mangel 表

Mangle 表用于指定如何处理数据包,它能改变 TCP 头中的 QoS 位,5 个内建链:


Raw 表

Raw 表用于处理异常,具有两个内建链:



  • NEW – meaning that the packet has started a new connection, or otherwise associated with a connection which has not seen packets in both directions, and
  • ESTABLISHED – meaning that the packet is associated with a connection which has seen packets in both directions,
  • RELATED – meaning that the packet is starting a new connection, but is associated with an existing connection, such as an FTP data transfer, or an ICMP error.

iptables 规则


  • Rules 包括一个条件和一个目标
  • 如果满足条件,就执行目标 target 中的规则或者特定值
  • 如果不满足条件,就判断下一条 rule

下面是 target 中指定的特殊值:

  • ACCEPT 允许防火墙接受数据包
  • DROP 防火墙丢弃包
  • QUEUE 防火墙将数据包移交到用户空间
  • RETURN 防火墙停止执行当前链后续 rules,并返回到调用链中


查看已添加的 iptables 规则

iptables -t filter --list           # 使用 -t 来指定表,默认为 filter 表
iptables -L -n
iptables -nvL --line-numbers


  • -t: 指定 table
  • -n:只显示 IP 地址和端口号,不将 ip 解析为域名

将所有 iptables 以序号标记显示

iptables -L -n --line-numbers


  • num 指定链中规则编号
  • target 前文中提及的 target 指定值
  • prot 协议 tcp, udp,icmp 等
  • source 数据包源 IP 地址
  • destination 数据包目标 IP 地址




使用 -A 命令追加新规则,其中 -A 表示 Append,新规则将追加到链尾。

iptables -A [chain] [firewall-rule]


  • -A chain 指定要追加规则的链
  • firewall-rule 具体的规则参数


-p 协议

可以使用 -p 来指定规则协议,比如 tcp,udp, icmp 等等,使用 all 来指定所有协议。

另外也可以使用协议值(比如 6 代表 tcp)来指定协议,映射关系可以查看 /etc/protocols

-s 源地址

使用 -s 来指定数据包的源地址,参数可以使用 IP 地址,网络地址,主机名

  • -s 指定 IP
  • -s 网络地址
  • 如果不指定 -s 表示所有地址

-d 目标地址

-d 来指定目的地址,参数和 -s 相同

-j 执行目标

-j 代表 jump to target,指定了当与规则匹配时如何处理包

可能值为 ACCEPT,DROP,QUEUE,RETURN,也能指定其他链(chain) 来作为目标

-i 输入接口

-i 代表输入接口,-i 指定了要处理来自哪个接口的数据包,这些包即将进入 INPUT,FORWARD,PREROUTE 链。

比如 -i eth0 指定了要处理通过 eth0 进入的数据包,如果不指定 -i 参数那么将处理所有接口的数据包。

  • ! -i eth0 处理所有经由 eth0 以外的接口进入的数据包
  • -i eth+ 将处理所有经由 eth 开头的接口进入的数据包

也可以使用 --in-interface

-o 输出

-o 代表 output interface, -o 制定了数据包由哪个接口输出,这些数据包即将进入 FORWARD,OUTPUT,POSTROUTING 链

如果不指定 -o 选项,那么系统上所有接口都可以作为输出接口

  • ! -o eth0 那么将从 eth0 以外的接口输出
  • -i eth+ 那么将仅从 eth 开头的接口输出

也可以使用 --out-interface 参数

–sport 源端口

针对 -p tcp 或者 -p udp 缺省情况下,将匹配所有端口。可以指定端口号或者端口名,比如

  • --sport 22
  • --sport ssh
  • --sport 22:100 # 使用冒号匹配端口范围

上述关系可以再 /etc/services 文件中查阅。

同理 --dport 是指定目的端口。

-P 设置内置 Chains


注意: 这几行命令不要轻易在服务器执行。

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

新建或者删除 Chain

使用 -N,比如:

iptables -t nat -N SHADOWSOCKS
iptables -t nat -X SHADOWSOCKS
iptables -t nat -E SHADOWSOCKS SS
iptables -t nat -F SHADOWSOCKS


  • -N 新建 Chain
  • -X 删除
  • -E 重命名
  • -F 删除 Chain 中所有规则


清除已有 iptables 规则

iptables -F     # 刷新所有链
iptables --flush     # 刷新所有链
iptables -t NAT -F      # 有些发行版 `-F` 命令并不会清除 NAT 表中的规则
iptables -X     # 删除表中所有非默认链


iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -s -d -j ACCEPT


iptables -A OUTPUT -j ACCEPT

允许访问 22 端口,允许某 IP 访问指定端口,以 22 端口为例命令是:

iptables -A INPUT -p tcp --dport 22 -j ACCEPT                         # 允许所有的 IP 访问 22 端口
iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT                        # 允许 22 端口发送数据
iptables -I INPUT -s -p tcp --dport 22 -j ACCEPT           # 允许某个 IP 访问
iptables -I INPUT -s -p tcp --dport 22 -j DROP             # 禁止某个 IP 访问
iptables -A INPUT -s -p tcp --dport 22 -j ACCEPT       # 允许 IP 段访问

允许外部访问 80 端口

iptables -A INPUT -p tcp --dport 80 -j ACCEPT

允许 FTP 服务的 21 和 20 端口

iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 20 -j ACCEPT



iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT



注意:如果 22 端口未加入允许规则,SSH 链接会直接断开

屏蔽单个 IP 的命令是

iptables -I INPUT -s -j DROP

封整个段即从 到 的命令

iptables -I INPUT -s -j DROP

封 IP 段即从 到 的命令

iptables -I INPUT -s -j DROP

封 IP 段即从 到 的命令是

iptables -I INPUT -s -j DROP

屏蔽某 IP 访问指定端口,以 22 端口为例命令是

iptables -I INPUT -s -p tcp --dport 22 -j DROP


要知道如何删除已添加的 iptables 规则,首先要查看规则 sudo iptables -L -n --line-numbers

比如要删除 INPUT 里序号为 8 的规则,执行:

iptables -D INPUT 8


保存生效的配置,让系统重启的时候自动加载有效配置(iptables 提供了保存当前运行的规则功能)

iptables-save > /etc/iptables.rules


iptables-restore < /etc/iptables.rules

但是系统并不会在启动时自动执行该规则,所以需要在 /etc/network/if-pre-up.d/ 目录中添加脚本

iptables-restore < /etc/iptables.rules



防止 DDos

iptables -A INPUT -p tcp --dport 80 -m limit --limit 30/minute --limit-burst 100 -j ACCEPT


  • -limit 30/minute: 最大每个分钟 30 个连接
  • limit-burst 100: 用来表示只有达到这个连接数量之后才会触发 limit/minute 限制


下面的例子,将 422 端口的流量转发到 22 端口,意味着 incoming ssh 连接可以从 22 端口或者 422 端口:

iptables -t nat -A PREROUTING -p tcp -d --dport 422 -j DNAT --to

另外也要显示的让 422 流量通过

iptables -A INPUT -i eth0 -p tcp --dport 422 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 422 -m state --state ESTABLISHED -j ACCEPT


2017-01-03 iptables , firewall , linux , network , command

Samba 使用

Samba,是种用来让 UNIX 系列的操作系统与微软 Windows 操作系统的 SMB/CIFS(Server Message Block/Common Internet File System)网络协议做链接的自由软件。1 Samba 能够为选定的 Unix 目录(包括所有子目录)创建网络共享。该功能使得 Windows 用户可以像访问普通 Windows 下的文件夹那样来通过网络访问这些 Unix 目录。

samba 有两个守护进程,smbd 和 nmbd,是 samba 的核心进程。nmbd 进程允许其他计算机浏览 Linux 服务器,smbd 进程在 SMB 服务请求到达时进行处理,并对共享的资源进行协调。


sudo apt install samba



启用 smb

sudo service smbd start

Samba 进程,使用 -D 参数开启守护进程。


sudo /etc/init.d/samba start


smbpasswd 命令属于 samba ,能够实现添加或删除 samba 用户和为用户修改密码。


smbpasswd [option] [username]

smbpasswd(选项)(参数) 选项

-a:向 smbpasswd 文件中添加用户;
-c:指定 samba 的配置文件;
-x:从 smbpasswd 文件中删除用户;
-d:在 smbpasswd 文件中禁用指定的用户;
-e:在 smbpasswd 文件中激活指定的用户;

用户名:指定要修改 SMB 密码的用户。


首先在 /etc/passwd 中添加一条,按照此格式:用户名:密码:uid:gid: 用户描述:主目录:登陆 shell


然后添加 Samba 用户:

smbpasswd -a einverne


smbpasswd einverne


Samba 的配置文件地址在 /etc/samba/smb.conf

    netbios name = OpenWrt
    display charset = UTF-8
    interfaces = lo ipv6 address/60 br-lan
    server string = OpenWrt Samba Server        # 服务器说明,显示了 samba 版本信息,可自定义
    unix charset = UTF-8
    workgroup = WORKGROUP	# Windows 默认
    host allow =                                # 可以把 ip 写全或只写前几位,表示允许访问服务端的客户端,与 hosts deny 刚好相反
    browseable = yes
    deadtime = 30		# This is useful to stop a server's resources being exhausted by a large number of inactive connections
    domain master = yes
    encrypt passwords = true
    enable core files = no
    guest account = root
    guest ok = yes
    #invalid users = root
    local master = yes
    load printers = no
    log file = /var/log/samba/%m.log            # 日志文件位置
    max log size = 50                           # 文件大小设置,单位是 M
    map to guest = Bad User
    max protocol = SMB2
    min receivefile size = 16384
    null passwords = yes
    obey pam restrictions = yes
    os level = 65
    passdb backend = smbpasswd                  # 用户名密码存放方式
    preferred master = yes
    printable = no
    security = user                             # 设置 samba 的安全等级
    smb encrypt = disabled
    smb passwd file = /etc/samba/smbpasswd
    socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=40960 SO_SNDBUF=40960
    syslog = 2
    strict allocate=no
    use sendfile = yes
    writeable = yes
    large readwrite = yes
    aio read size = 40960
    aio write size = 40960
    read raw = yes
    write raw = yes

    path = /home/user			# 目录
    browseable  = no
    writable = yes              # 是否可写
    valid users = %S            # 具有合法登陆身份的用户登陆时,家目录变为自己的家目录

# 创建了一个 Share 名为 OpenWrt
    path = /mnt/sda1			# 目录
    valid users = root			# 允许 root 读写操作
    read only = no				# 允许写
    guest ok = no				# 不允许匿名
    create mask = 0777			# 新文件权限
    directory mask = 0777		# 新文件夹权限

[public]                        # 公共目录访问
    comment = Public Stuff      # 注释
    path = /home/samba
    public = yes
    writable = yes
    write list =+staff          # 该目录除了 staff 的组员拥有读写权限外,其他用户仅可读

Samba 安全等级可选值有 4 种

  • user 由提供服务的 samba 服务器负责检查账户及密码(默认)
  • share 无需共享密码,任何人都可以访问 samba 资源
  • server 该级别下,身份验证由 windows 主机或者 samba 负责
  • domain 身份验证由另一台 windows 主机负责

用户名密码存放方式设置可选值有 3,默认为 tdbsam,位置 /var/lib/samba/private/passwd.tdb

  • smbpasswd 使用 /etc/samba/smbpasswd 给系统用户设置 samba 密码,这种方式,用户必须为系统用户
  • tdbsam 使用数据库文件 passdb.tdb,可用 smbpasswd -a 创建 samba 用户,也可用 pdbedit 创建
  • ldapsam 使用 ldap 方式验证用户

其中如果选择使用 tdbsam 那么用户管理可以使用如下方法

pdbedit -a username              新建 samba 账户
pdbedit -x username              删除 samba 账户
pdbedit -L                               列出 samba 用户列表,读取 passdb.tdb
pdbedit -Lv                             列出 samba 用户列表详细信息
pdbedit -c “[D]” -u username  暂停该 samba 用户账号
pdbedit -c “[]” -u username     恢复该 samba 用户账号


正如上面提到的,创建一个新的名为 Openwrt 的共享,需要有些配置,有些配置看名字就能够看出,但是有一些有些复杂。


    path = /media/movie
    comment = this is folder sync from bt
    read only = yes
    guest ok = yes
    create mask = 0777			# 新文件权限
    directory mask = 0777		# 新文件夹权限


  • create mode – 这个配置定义新创建文件的属性。Samba 在新建文件时,会把 dos 文件的权限映射成对应的 unix 权限,在映射后所得的权限,会与这个参数所定义的值进行与操作。然后再和下面的 force create mode 进行或操作,这样就得到最终 linux 下的文件权限。
  • force create mode – 见上面的描述。相当于此参数所设置的权限位一定会出现在文件属性中。
  • directory mode – 这个配置与 create mode 参数类似,只是它是应用在新创建的目录上。Samba 在新建目录时,会把 dos–>linux 映射后的文件属性,与此参数所定义的值相与,再和 force directory mode 相或,然后按这个值去设置目录属性。
  • force directory mode – 见上面的描述。相当于此参数中所设置的权限位一定会出现在目录的属性中。
  • 说明一点,上面的 create mode 和 create mask 参数是同义词,用哪个都可以;而 directory mode 和 directory mask 参数是相同的。



    path = /home/samba
    writable = yes          # 是否可写
    public = yes            # 是否公开
    browseable = yes        # 是否允许在工作组
    create mode = 0655
    directory mode = 0755   # 设置不同的用户登陆后创建的文件和文件夹权限
    valid users = user,user1,@share    # 允许访问该共享的用户名(多个用户或者组中间用逗号隔开,组用“@组名”表示)

若希望每个人创建的内容都可以被其他人修改,则设置为 0770, 若希望每个人创建的内容只能被自己修改,分别设置 create 为 0655 和 directory 为 0755

useradd user
useradd user1
groupadd share
usermod -aG share user
usermod -aG share user1
mkdir /home/samba
chmod 777 /home/samba
chgrp share /home/samba
echo "example" >  /home/samba/file1.txt
smbpasswd -a user
smbpasswd -a user1


客户端验证 Linux 访问 samba:

smbclient -L  -u user     # 密码是自己设置的密码,查看共享内容
smbclient // -U user       # 密码是自己设置的密码,ls 可看到共享的详细内容

客户端挂载命令为(客户端需安装 cifs-utils)

mount -t cifs -o username=einverne,password=xxxxx // /home/samba


2016-12-27 samba , smb , openwrt , linux

2016 年读书笔记

又到了一年的年末,翻开去年的记录,吃惊的发现去年竟然只看过 16 本。今年年初的时候,计划阅读 100 本书,也的的确确一直坚持了一年,中途可能因为工作耽误了一些进度,但也一直坚持到现在。然而遗憾的是到目前为止,距离 2016 年结束还有短短一个礼拜的时候,又发生了和去年一样的问题,欠下了 10 本左右的债。


今年的书单印证了一句话“因为一本书,爱上一个人,迷上一个类型”,我也曾经在 G+ 上说过,多少年了,还是在三年级到初中的那段时间疯狂的迷过 Verne,多少年的时间里因为学业,因为各种,再难爱上一位作家,再难爱上一段文字。而今年因为一本《解忧杂货铺》让我知道了东野圭吾,也打开了我认知的另一扇窗户。今年的近 90 本中有很大一部分都是东野的作品。而有趣的事,和东野的经历一样,让我们结识悬疑推理的经历竟然如此的相似,这一段经历可以参考 《我的晃荡的青春》,东野的青春竟然也如此的淘气和真实。

而我从年初,从东野最著名的小说开始读《嫌疑人 X 的献身》、《白夜行》在到加贺恭一郎系列,再甚至到不怎么出名,甚至默默无闻的早期作品《以眨眼干杯》《沉睡森林》,再到毒舌三部曲《毒笑小说》《黑笑小说》《怪笑小说》,东野圭吾的书读不到尽头也几乎没有重复,这让我佩服的五体投地。


  • 解忧杂货铺 五星
  • 白夜行 五星
  • 空中杀人现场,短篇,四星
  • 嫌疑人 X 的献身,五星
  • 秘密 五星
  • 放学后 四星
  • 恶意 五星
  • 流星之绊 五星
  • 彷徨之刃 五星,强烈推荐
  • 幻夜 四星
  • 信 五星
  • 单恋 四星
  • 时生 四星
  • 名侦探的守则 四星
  • 圣女的救济 五星
  • 宿命 四星
  • 超杀人事件 五星,短篇可以看看
  • 名侦探的诅咒 四星
  • 浪花少年侦探团 四星
  • 再见了忍老师 四星
  • 十一字杀人 四星
  • 没有凶手的杀人夜 四星
  • 分身 四星
  • 同级生 四星
  • 只差一个谎言 四星
  • 祈祷落幕时 四星
  • 虚无的十字架 五星
  • 湖畔杀人事件 四星
  • 布鲁特斯的心脏 三星
  • 毒笑小说 五星
  • 从前我死去的家 四星
  • 新参者 五星
  • 黑笑小说 五星
  • 天空之蜂 四星
  • 美丽的凶器 四星
  • 濒死之眼 四星
  • 杀人之门 四星
  • 以眨眼干杯 四星
  • 毕业 四星
  • 学生街杀人 四星
  • 我的晃荡的青春 四星
  • 红手指 四星
  • 谁杀了她 四星
  • 怪人们 四星
  • 麒麟之翼 四星
  • 梦幻花 四星
  • 变身 五星
  • 假面饭店 四星
  • 天使之耳 五星
  • 沉睡的森林 四星

今年的书摘如果都放到这边可能有些多,甚至没有什么必要,有些内容经过整理和摘录,我都放到了 Evernote 。有些比较长的内容,也有格式化。


  • 围城,毕竟有些年代,不过依然值得一读
  • 追风筝的人,带领我走进阿富汗
  • 灿烂千阳,追风筝同作者的书,依然讲述阿富汗的故事
  • 岛上书店,毕竟畅销书,明年可以按比例提高产销书比例


但回头看自己今年的书单,深感技术类书籍占比略少,去年至少系统的看过 Bash,和基础 Linux,而今年除了看一些基础的 Java 知识,再没有系统地学习一项内容,除了年末恶补了一些 Spring MVC 和 Redis, HBase 的相关知识。因此在制定明年的计划时要讲技术书籍内容比例提高到 10% 左右,有些书值得反复阅读思考和实践,技术类的书既有消费品也有值得反复品味的内容。


  • Effective Java 五星,所有 Java 编程者都应该读一读
  • Java 与 模式,稍显啰嗦,但是讲的非常细致
  • Maven 实战,熟悉 Maven 入门速成
  • Redis 入门指南,入门书籍,不讲求细节和实现原理
  • 其他的都没有完整的读完,明年一定要提高一定的比率。



  • 摄影师的视界,迈克尔弗里曼摄影构图与设计,讲构图的书,还是值得一看,只是还没有来得及实践
  • 穿透黑暗夜景和暗光摄影,匆匆读过,夜间摄影还是需要一些技巧
  • 昨天的中国,在学校法盟偶然遇见的一本纪实摄影,顶赞


  • 设计准则,第一次参加读书会时借阅的书,讲到一些日常生活中的设计,当要装修的时候再参阅
  • 设计心理学


  • 人在欧洲,真的是讲人在欧洲的一些见闻和思考感悟
  • 民主的细节,五星强烈推荐
  • One Billion Customers ,五星强烈推荐
  • 黑客与画家,其实早读过,今年又翻出来推荐给一些人
  • 乖,摸摸头,小故事,有人说的”鸡汤“
  • 秦始皇的秘密,也是听人推荐一口气读完的,当故事看吧
  • 断舍离,整理啊
  • 怦然心动的人生整理魔法 1,2 第一部比较笼统,第二部比较仔细,第二部中的衣服整理法则好好
  • 从你的全世界路过,畅销书,小故事看吧
  • TED 演讲的 8 个秘诀
  • 失控,大部头的书,好像就记得蜜蜂了。
  • 三人行,第一次见到那么排版的书籍, 针对同一个主题,两岸三地不同世界的人不同的故事。

还有一些就不列 了。

2016-12-22 book , reading



  • 配置 Rime 在 Vim 下退出编辑模式时自动切换成英文输入法 半年以前在 Obisidian 的文章下面有人曾经问过我一个问题,如何在 Vim 或者其他使用 Vim 模式的编辑器,比如 IntelliJ,或者 Obisidian 开启 Vim 模式后方便地切换中英文输入法,因为在编辑模式和普通模式下,需要经常切换输入法,使得体验变得非常槽糕。
  • Asus RT-AC86U 设置 前些天给家里买手机正好凑单了一个 Asus RT-AC86U,正好可以代替出了两次故障的小米 3G。
  • 扩展 Proxmox 系统分区以及 Proxmox 文件系统初识 昨天想要扩展一下之前安装的 Proxmox 容量,对系统进行了一次关机,然而关机之后就悲剧的发现在 U 盘中的系统启动不了了,将 U 盘拔下检测之后发现 U 盘可能挂了,一个全新的 U 盘,在连续 192 天运行之后挂掉了。无奈之下只能想办法先恢复一下 Proxmox 系统以及安装在系统之上的 OpenMediaVault 了。
  • 『译』我最喜欢的命令行工具 偶然间看到一篇介绍 cli 的文章,感觉写得不错,正好借此机会也整理一下我之前使用过,以及觉得非常值得推荐的 CLI 工具。
  • 使用 Clonezilla 将硬盘中系统恢复到虚拟机中 今年陆陆续续将工作的环境迁移到了 macOS,虽然已经把日常的资料迁移到了 macOS,但是之前的 Linux 上还有一些配置,以及可以的一些测试还需要用到 Linux 虚拟机,所以我就想能不能用 Clonezilla 将磁盘中的系统备份然后恢复到虚拟机里面。因为我发现 macOS 下的 Fusion 还是很强大的。