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"

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>

	if (pledge("stdio", NULL) == -1)

	char *remote_ip;
	remote_ip = getenv("HTTP_X_FORWARDED_FOR");
	if (remote_ip == NULL)

	puts("Status: 200 OK\r");
	puts("Content-Type: text/html\r");
	printf("%s", remote_ip);

Here’s the Makefile I wrote to compile and install it:


CFLAGS  += -static -g -W -Wall -Wextra

example: example.c
        ${CC} ${CFLAGS} example.c -o $@

all: example

        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.