Just wanted to share my solution to my own problem, listed a few posts above this one.
I now run a master server on a static IP. When a game server is run, it first connects as a client to the master server, and tells it "Hi, I'm a game server, this is my IP". The master server sends an acknowledgement and then drops the connection. The game server then sets up fresh netcode as a server, and begins accepting connection from game clients. If the game server is exited normally, it drops all client connections, becomes a client and connects to the master server again, telling it "We're done here, I'm out". The master server receives this signal, removes that game server's IP from its list and drops the connection. Then the game server terminates.
When clients wish to connect to a game server, they first connect to the master server on the master IP and sends it "Hi, I'm a game client, this is my authentication key". The master server checks the key and validates it. If the validation check fails, the client is immediately disconnected. If the check passes, the master server sends the client a list of game server IP's. The client can then choose one, drop the connection to the master server and establish one to the selected game server.
The advantages of this system are that the master server can enforce authentication key validation, which will provide for suitable copy protection. Additionally, this system is a pretty common way of registering servers for clients to find, so your server will always be listed for all clients. Because every client will connect to the master server during its startup, the master server can send things like message of the day and development news to clients so they can be kept up to date.
There are two fairly major disadvantages to this system though. If the master server goes down, no client in the world will be able to play the game at all. This holds true for most commercial multiplayer games however, so this could still be acceptable provided I field a nice and stable master server. The other substantial disadvantage is that if a game server quits in any way other than normally (ie, crash or Alt-F4 rather than a typed QUIT command) then the master server will never be notified that this game server is offline.
I wanted to have the master server periodically ping all game servers that it's aware of to see if they are still alive and remove any game server that doesn't respond. There seems to be no way to do this, though. If I can find a way to accomplish this periodic check-alive ping while continuing to serve clients (or to have game servers periodically send a keep-alive ping to the master server while still serving their clients) then this will no longer be a problem.
Any ideas?