最近工作裏遇到的一些問題,記錄下來

最近在工作裏,遇到了幾個問題,記錄下來

1、首先是轉發程序rinetd

下載安裝:

wget http://www.boutell.com/rinetd/http/rinetd.tar.gz
tar -zxvf rinetd.tar.gz
make
make install

rinetd使用方法:

pkill rinetd  //關閉進程
rinetd -c /etc/rinetd.conf  //啓動轉發

查看狀態
netstat -antup


配置:

 本機IP 端口 轉發到的ip 端口

1.2.3.4 11 2.3.4.5 6011
1.2.3.4 12 3.4.5.6 7012

allow *.*.*.*
logfile /var/log/rinetd.log



但是在使用過程中,發現沒有日誌記錄,查看rinetd的源碼,發現rinetd在被kill結束的
時候才把日誌寫到文件裏,所以修改日誌記錄函數,增加int fflush(FILE *stream)函數
void log(int i, int coSe, int result)
{
	unsigned char *reAddress;
	int bytesOutput;
	int bytesInput;
	/* Bit of borrowing from Apache logging module here,
		thanks folks */
	int timz;
	struct tm *t;
	char tstr[1024];
	char sign;
	if (!log) {
		return;
	}
	t = get_gmtoff(&timz);              //獲取當前系統時間
	sign = (timz < 0 ? '-' : '+');
	if (timz < 0) {
		timz = -timz;
	}
	strftime(tstr, sizeof(tstr), "%d/%b/%Y:%H:%M:%S ", t);
	
	if (i != -1) {
		reAddress = reAddresses + i * 4;
		bytesOutput = coBytesOutput[i];
		bytesInput = coBytesInput[i];
	} else {
		reAddress = nullAddress;
		bytesOutput = 0;
		bytesInput = 0;
	}
	if (logFile) {
		if (logFormatCommon) {
			/* Fake a common log format log file in a way that
				most web analyzers can do something interesting with.
				We lie and say the protocol is HTTP because we don't
				want the web analyzer to reject the line. We also
				lie and claim success (code 200) because we don't
				want the web analyzer to ignore the line as an
				error and not analyze the "URL." We put a result
				message into our "URL" instead. The last field
				is an extra, giving the number of input bytes,
				after several placeholders meant to fill the 
				positions frequently occupied by user agent, 
				referrer, and server name information. */
			fprintf(logFile, "%d.%d.%d.%d - - "
				"[%s %c%.2d%.2d] "
				"\"GET /rinetd-services/%s/%d/%s/%d/%s HTTP/1.0\" "
				"200 %d - - - %d\n",
				reAddress[0],
				reAddress[1],
				reAddress[2],
				reAddress[3],
				tstr,
				sign,
				timz / 60,
				timz % 60,
				seFromHosts[coSe], seFromPorts[coSe],
				seToHosts[coSe], seToPorts[coSe],
				logMessages[result],
				bytesOutput,
				bytesInput);
		} else {
			/* Write an rinetd-specific log entry with a
				less goofy format. */
			fprintf(logFile, "%s\t%d.%d.%d.%d\t%s\t%d\t%s\t%d\t%d"
					"\t%d\t%s\n",
				tstr,													//時間和日期  
				reAddress[0],reAddress[1],reAddress[2],reAddress[3],	//客戶端IP(自助終端ip)
				seFromHosts[coSe],										//監聽ip
				seFromPorts[coSe],										//監聽端口
				seToHosts[coSe],										//轉發到的地址
				seToPorts[coSe],										//轉發到的端口
				bytesInput,												//客戶端接收到的數據大小
				bytesOutput,											//客戶端發送的數據大小
				logMessages[result]);									//結果
		}
		fflush(logFile);          //增加fflush()函數,清空緩衝區,使得緩衝區的內容寫到文件裏
	}
}
然後再編譯安裝,查看日誌,正常。

2、由於rinetd轉發程序是內網轉外網的,所以服務器需要設置雙網卡和路由選擇
測試服務器是虛擬機,首先是虛擬機設置雙網卡,VMnet0綁定本機的外網網卡(無線網卡),
VMnet2綁定本機的內網網卡(有線網卡)
如圖所示:


然後設置虛擬機,添加一個網卡


設置網卡



然後重啓服務器,在服務器裏添加一個網絡,eth0綁定外網網卡,eth1綁定內網網卡

最後一步就是設置路由,其實就是添加設置默認網關

命令:
route add default gw 192.168.0.1

重啓網絡 service network restart

實現服務器連接內外網


3、弄好了轉發程序和網絡後,部署測試,A爲內網機器,B爲轉發前置機(rinetd),

C爲轉發到的外網機器

發現A telnet到B,第一次通,第二次不通的情況,決定抓包

tcpdump -i eth1 -nn 'port 6000' > /root/Desktop/rinetd_log/rinetd_tcpdump_log

 > /root/Desktop/rinetd_log/rinetd_tcpdump_log  爲存放抓取的包的文件
查看抓取的包的內容發現第二次telnet握手不成功


第二次telnet:
A三次握手到B(連續發了三次第一次握手(都不成功))
16:47:18.224898 IP A > B: S 221780606:221780606(0) win 65535 <mss 1448,nop,wscale 3,nop,nop,timestamp 0 0,nop,nop,sackOK>                  

16:47:21.151045 IP A > B: S 221780606:221780606(0) win 65535 <mss 1448,nop,wscale 3,nop,nop,timestamp 0 0,nop,nop,sackOK>

16:47:27.167100 IP A > B: S 221780606:221780606(0) win 65535 <mss 1448,nop,wscale 3,nop,nop,timestamp 0 0,nop,nop,sackOK>

上網查了一下,原來是A機器的syn包帶有時間戳,經過NAT轉換後,如果使用的端口被之前使用過,而且時間戳大於本次syn包中的時間戳。系統將會直接丟棄。造成本次鏈接無法正常完成TCP/IP的3次握手。

解決辦法:

設置sysctl.conf裏面tcp_timestamps=0也可以只用命令sysctl -w net.ipv4.tcp_timestamps=0

設置完成後,多次telnet都行了


所有事情完成後,測試環境測試通過。


寫得有點亂,有哪裏不對的地方,請指出來

轉載請註明出處,謝謝。







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章