Itay Grudev
Itay Grudev

Reputation: 7444

Reliable (cryptographic) way to verify a devices public IP address behind a NAT

I am writing a relatively small bash script that is supposed to update DNS records for a server behind a NAT which might change its external IP address. Essentially a free DynDNS using my DNS provider's API.

I am retrieving the server's IP address using a simple query to an external service. But for the sake of security, before pointing my DNS A record to a new arbitrary IP address given to my by an external service I first need to verify that this indeed is the server's IP address. And this check would need to involve a cryptography step since an active MITM attack could be taking place and just forwarding traffic to the server's real IP address.

So what would be the simplest way (if possible through bash) to verify that this is indeed the server's IP address?

Upvotes: 0

Views: 104

Answers (2)

Itay Grudev
Itay Grudev

Reputation: 7444

Assuming that $IP is the server's new external IP address, this works by first acquiring the servers SSH keys by running ssh-keyscan on localhost and generating a temporary known hosts file. It then substitutes 127.0.0.1 with the given $IP and initiates an ssh session with the temporary known hosts file to the remote IP address. If the session is established and the key verification is successful the command will exit cleanly. Otherwise it will output the Host key verification failed. message. This will work even if authentication with the server fails as host key verification is done before authentication. The script finally checks whether the ssh output includes the given error message and returns valid or invalid correspondingly.

TMP_KNOWN_HOSTS=$(mktemp)
ssh-keyscan 127.0.0.1 > $TMP_KNOWN_HOSTS
sed -i "s/127\.0\.0\.1/$IP/" $TMP_KNOWN_HOSTS
RESPONSE=$(ssh -n -o "UserKnownHostsFile $TMP_KNOWN_HOSTS" -o "StrictHostKeyChecking yes" $IP true 2>&1)

if ! [[ $RESPONSE = *"Host key verification failed."* ]]; then
  echo "valid"
else
  echo "invalid"
fi

Upvotes: 0

symcbean
symcbean

Reputation: 48387

I presume you mean that the bash script is running somewhere other than the server whose IP you need to determine?

The obvious solution would be to connect using ssh with strict host checking (and a remembered server key) or via SSL with certificate versification (you could use a self-signed certificate). The former is a bit easier to do out of the box.

Upvotes: 0

Related Questions