I want to write a program with HTTP server functionality on my Linux machine so that it can interact with my browser for showing formatted output etc.
After some research I decided to go with libmicrohttpd. A very basic server is quite easy to implement with this library. Based on the tutorial, the following code already does the trick.
#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;
}
Now my problem is that I do not know how to make sure that I do not accidentally expose any of my data over the network by running this server and letting it serve real data. I am not very experienced with network programming and it was hard for me to find explicit information on that in this context.
So to be more precise, my Question: Do I have to change something in the above program/on my system/in my router for making sure that the open port 8888 is only visible and accessable from localhost?
Note: Accomplishing this with libmicrohttpd would be nice, but not strictly necessary. If another approach/library is more secure, I am ready to give it a try.
You should use the MHD_OPTION_SOCK_ADDR to bind to only INADDR_LOOPBACK. This will make sure you do not listen on anything other than the loopback address and will guarantee, no external machine can connect.
The modified code looks something like following
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;
}
Also man bind would help to find out about binding to an address to listen to.
You can test this by running netstat -ln -tcp after running the server.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With