gpt4 book ai didi

c++ - 如何让我的 TCP 监听应用程序更安全?

转载 作者:行者123 更新时间:2023-11-28 08:16:21 28 4
gpt4 key购买 nike

我正在寻找有关编写将监听 tcp 端口的非常安全的 C/C++ 应用程序的建议。我想看看其他人试图对我的机器做什么,但如果我可以用一个非常短的程序来完成我需要的事情,我宁愿不安装精心设计的蜜 jar 应用程序。我的目标是简单和安全,我想确保至少处理以下内容:
1) 客户端不能发送无限量的数据,
2) 客户端不应该有过多的连接使服务器过载并且
3) 客户端不应该无限期地保持连接打开。
因为我当前的应用程序很小而且功能齐全,所以这个项目似乎不需要第三方库。然而,一个可以进一步简化应用程序的小型库会很有趣。此外,我希望 C++ 标准库可以帮助简化我的代码。

以下是我最初尝试的一些关键功能。此代码可在 Windows、OSX 和 Linux 上编译。

如何使应用更安全或更简单?

void SafeClose(SOCKET s)
{
if (s == INVALID_SOCKET)
return;
shutdown(s, SHUT_RDWR);
closesocket(s);
}

void ProcessConnection(SOCKET sock, sockaddr_in *sockAddr)
{
time_t time1;
char szTime[TIME_BUF_SIZE];
char readBuf[READ_BUF_SIZE];

time(&time1);
strftime(szTime, TIME_BUF_SIZE-1, "%Y/%m/%d %H:%M:%S", localtime(&time1));
printf("%s - %s\n", szTime, inet_ntoa(sockAddr->sin_addr));
usleep(1000000); // Wait 1 second for client to send something
int actualReadCount = recv(sock, readBuf, READ_BUF_SIZE-1, 0);

if (actualReadCount < 0 || actualReadCount >= READ_BUF_SIZE){
actualReadCount = 0;
strcpy(readBuf, "(Nothing)");
} else {
CleanString(readBuf, actualReadCount); // Replace non-printable characters
readBuf[actualReadCount] = 0;
}

printf("%s\n\n", readBuf);
SafeClose(sock);
}


int main(int argc, char* argv[])
{
int port = 80;
char cmd[CMD_BUF_SIZE] = {0};
sockaddr_in newSockAddr;
sockaddr_in localSockAddr;

if(argc < 2){
printf("Usage: safelisten PORT\n\n");
return error_code;
}

error_code++;
port = atoi(argv[1]);
BuildCleanAsciiMap(); // Used to replace non-printable characters

localSockAddr.sin_family = AF_INET;
localSockAddr.sin_addr.s_addr = INADDR_ANY;
localSockAddr.sin_port = htons(port);
sizeNewSockAddr = sizeof newSockAddr;

CHK( listenSocket = socket(AF_INET, SOCK_STREAM, 0));
CHK( setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)));
CHK( bind(listenSocket, (sockaddr*)&localSockAddr, sizeof localSockAddr));
CHK( listen(listenSocket, BACKLOG));
CHK( SetNonBlocking(listenSocket));
CHK( SetNonBlocking(0)); // Set STDIN to nonblocking for linux
printf ("Listening on port: %d\nEnter q to quit.\n\n", port);

while(strcmp(cmd, "q")) // While the user has not entered q ...
{
newSocket = accept(listenSocket, (sockaddr*)&newSockAddr, &sizeNewSockAddr);
ReadCmd(cmd, CMD_BUF_SIZE);

if(newSocket == INVALID_SOCKET) {
// accept() would have blocked, thus we wait and try again
usleep(10000);
continue;
}

// Set to nonblocking because we don't want the client to dictate how
// long we are connected.
CHK( SetNonBlocking(newSocket));
ProcessConnection(newSocket, &newSockAddr);
}

SafeClose(listenSocket);
return 0;
}

最佳答案

2) The client(s) should not be able to overload the server with too many connections...

您最好的选择是让路由器限制一个 IP 地址建立的连接数,因为当您的程序获取连接信息时,系统资源已经分配完毕。

1) The client should not be able to send an unlimited amount of data,

最好的选择是有一些可以发送的合理最大值,并且只跟踪您已阅读了多少,一旦达到最大限制,就关闭连接。

3) The client should not be able to keep a connection open indefinitely.

为此,您可以只创建一个线程来开始倒计时,这样当连接打开特定时间后,它会超时,您可以关闭连接。

还有其他更复杂的解决方案,但我认为这是一个很好的起点。

如果你想对 (2) 做些什么,在内存中保留一个 hashmap 并只增加已建立的连接数,但你可能还想跟踪时间。你希望数据结构非常快,所以你可以决定是否需要提前断开连接。

例如,如果你在 hashmap 中有两个 long,那么你可以把第一个连接的时间(以 unixtime 或 ticks 为单位),并递增,如果你在不到一分钟内获得 10 个连接,则开始关闭直到一分钟过去了。如果该元素的连接时间足够长以至于您相信它不会攻击您,则将其删除。

此外,请确保您验证了传递给您的所有参数,并为任何字符串设置合理的最大值。

关于c++ - 如何让我的 TCP 监听应用程序更安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7628653/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com