从外部

时间:2017-09-03 12:21:09

标签: c linux http networking server

我想在我的Linux机器上编写一个具有HTTP服务器功能的程序,以便它可以与我的浏览器进行交互以显示格式化的输出等。

经过一番研究后,我决定选择libmicrohttpd。使用此库非常容易实现非常基本的服务器。基于tutorial,以下代码已经成功。

#include <sys/types.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <string.h>
#include <microhttpd.h>
#include <stdio.h>

#define PORT 8888

static int
answer_to_connection(void *cls, struct MHD_Connection *connection,
                     const char *url, const char *method,
                     const char *version, const char *upload_data,
                     size_t *upload_data_size, void **con_cls)
{
  const char *page = "<html><body>Hello, browser!</body></html>";
  struct MHD_Response *response;
  int ret;
  response = MHD_create_response_from_buffer(strlen(page), (void*)page,                              
                                             MHD_RESPMEM_PERSISTENT);
  ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
  MHD_destroy_response(response);
  return ret;
}


int main()
{
  struct MHD_Daemon *daemon;    
  daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL,
                            &answer_to_connection, NULL, MHD_OPTION_END);
  if (NULL == daemon) return 1;
  (void)getchar();
  MHD_stop_daemon(daemon);
  return 0;
}

现在我的问题是我不知道如何通过运行此服务器并让它提供真实数据来确保我不会通过网络意外暴露我的任何数据。我对网络编程不是很熟悉,在这种情况下我很难找到关于它的明确信息。

更确切地说,我的问题:我是否必须更改上述程序/我的系统/路由器中的某些内容,以确保开放端口8888仅可见且可访问来自localhost?

注意:使用libmicrohttpd完成此操作会很不错,但并非绝对必要。如果另一种方法/库更安全,我准备尝试一下。

3 个答案:

答案 0 :(得分:4)

您应该使用MHD_OPTION_SOCK_ADDR仅绑定到INADDR_LOOPBACK。这样可以确保您不会监听环回地址以外的任何内容,并且可以保证不会连接任何外部计算机。

修改后的代码类似于

int main()
{
    struct MHD_Daemon *daemon;
    struct sockaddr_in loopback_addr;

    memset(&loopback_addr, 0, sizeof(loopback_addr));
    loopback_addr.sin_family = AF_INET;
    loopback_addr.sin_port = htons(PORT);
    loopback_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

    daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY,
                        PORT,
                        NULL,
                        NULL,
                        &answer_to_connection,
                        NULL,
                        MHD_OPTION_SOCK_ADDR, (struct sockaddr *)(&loopback_addr),
                        MHD_OPTION_END);

    if (daemon == NULL) return 1;
    (void)getchar();
    MHD_stop_daemon(daemon);
   return 0;
}

同样man bind将有助于找出绑定到要收听的地址。

您可以在运行服务器后运行netstat -ln -tcp进行测试。

答案 1 :(得分:-1)

正如@stark评论的那样,采用unix精神“完美处理任务的小而不同的工具”:使用webserver处理http请求,使用iptables等防火墙或新的nftables来保护你的服务器免受外界攻击

答案 2 :(得分:-1)

为简单起见,IP地址指定Internet中的计算机,并且端口(例如8888,80等)将确定您要在一台计算机中访问哪些应用程序。 通常,IP地址分为两类:公共和私有。如果您想获得公共IP地址(例如202.117.21.116),则需要付费,然后您的计算机和应用程序将在Internet中找到。如果您拥有专用IP地址(例如192.168。或127. 。*等),则无法直接在Internet上找到您的计算机。我认为您的IP地址是私有的,您的数据永远不会暴露给Internet上的其他人,但如果他们知道您的IP地址和您的HTTP服务器端口,那么您的HTTP服务器应用程序将由局域网中的人发现(8888)。虽然您的计算机可以在局域网中找到,但只允许访问您在HTTP服务器中指定的数据,而不是计算机中的所有数据。 因此,您可以使用localhost访问您的应用程序,而局域网中的其他人只能获取数据----“Hello,browser!”您在程序中指定的,而Internet中的其他人无法访问您的计算机。