A Simple Whats-my-IP Service
I have some simple scripts that require the system to discover what its public IP address is so that when it changes, those scripts can update DNS accordingly.
I went for a really simple, but not-so-secure solution: Install php-fpm and have it print $_SERVER[‘X-FORWARDED-FOR’] back.
This isn’t great and PHP has a lot of security problems.
httpd and slowcgi
OpenBSD base comes with a great web server: httpd(8) and a way to execute common gateway interface (CGI) programs: slowcgi(8).
This is a snippet from httpd.conf
to handle the output:
location "/example" {
root "/cgi-bin"
fastcgi
}
We’ll assume you have httpd already set up and enabled.
Ensure slowcgi is enabled and started:
doas rcctl enable slowcgi
doas rcctl start slowcgi
The source code
Here’s our example.c
script that will output the remote IP address. We are using pledge(2) to only allow stdio
.
/*
* Very simple CGI program to output the IP address you're coming from
*/
#include <err.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int
main(void)
{
if (pledge("stdio", NULL) == -1)
err(EXIT_FAILURE, NULL);
const char *remote_ip;
remote_ip = getenv("HTTP_X_FORWARDED_FOR");
if (remote_ip == NULL)
err(EXIT_FAILURE, NULL);
puts("Status: 200 OK\r");
puts("Content-Type: text/html\r");
puts("\r");
printf("%s", remote_ip);
return(EXIT_SUCCESS);
}
Here’s the Makefile
I wrote to compile and install it:
PREFIX?=/var/www
CFLAGS += -static -g -W -Wall -Wextra
example: example.c
${CC} ${CFLAGS} example.c -o $@
all: example
clean:
rm example
install: example
install -o www -g www -m 500 example ${PREFIX}/cgi-bin/example
Once you run make
and doas make install
it will install it to the /var/www
chroot into the /cgi-bin
directory with secure permissions and then if you go to your web server to /example
you should see your remote IP address provided the server is on the internet and not in your internal network.