最近在工作里,遇到了几个问题,记录下来
1、首先是转发程序rinetd
下载安装:
wget http:
//www.boutell.com/rinetd/http/rinetd.tar.gz
tar -zxvf rinetd.tar.gz
make
make install
rinetd使用方法:
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
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()函数,清空缓冲区,使得缓冲区的内容写到文件里
}
}
然后再编译安装,查看日志,正常。
然后重启服务器,在服务器里添加一个网络,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都行了
所有事情完成后,测试环境测试通过。
写得有点乱,有哪里不对的地方,请指出来
转载请注明出处,谢谢。