My DNS record can only point to an IP address. How do I make it reach for a port?
I am fairly new to network administration and therefore am already excited to have successfully set up a DNS record.
Now I am a bit confused, because I would like to have this URL:
http://www.example.org:8080/fetch/characters/
be actually reached by this
http://www.example.org/fetch/characters/
So users can reach the service on port 8080 without having to explicitly set the port.
How can I do this? Do I need some special application on my server? Or any redirect stuff to be applied to requests?
Solution 1:
DNS records can't point to ports (with a few special case exceptions that do not apply here).
If you have a web service listen on port 8080 and want to reach it without specifying this port, you have 3 options:
- Make it actually listening on port 80 (or 443 with https).
- Configure whatever is already listening on port 80 to forward requests to your service on port 8080 (reverse proxy).
- If you can live with a redirect, use this instead of a proxy, but then your clients will see the
:8080
part in their address bars after the redirect.
Solution 2:
Web servers listen to TCP port 80 by default. If you don't want to type the port number in the URL explicitly, you have a few options:
-
You can reconfigure your web server to use port 80 instead of port 8080. This is recommended for web servers like nginx or Apache but not for web servers like Gunicorn. This option also is not always possible as that port might already be in use by a different web server.
Also, when your server is behind a NAT gateway, it doesn't own the public IP address and the combination of that public NAT address and port 80 might already be forwarded to a different web server.
You can put a reverse proxy server in front of your web server which accepts the traffic on TCP port 80 and sends it to your web server on TCP port 8080. This will also work if port 80 is already in use. Simply put the reverse proxy server in front of both web servers, making them both listen to ports other than 80.
In order to provide better and more detailed help on which option might be best and the limitations etc, we need to know more about your setup. Hopefully this explanation already clarified things a bit.
Solution 3:
Simple answer, related to level of question
Ignoring exotic uses of DNS, and also reverse DNS lookup (not relevant to question), almost all DNS use is of the form:
- Client sends domain name (fully qualified or otherwise) to a DNS server
- DNS server returns domain information from its records. Usually the key information requested is either the IP address to communicate with web/email on that domain, or the IP address of another DNS server better able to provide that information.
Once the client has contacted the server, the server itself will take over and the DNS system drops out of the picture.
What that means is, the the DNS system doesn't need to supply port information, and it almost never does so. So although the aim of the question is valid, and often done, it isn't actually the DNS system which does it. That's why you can't work it out :)
The idea is that once your client can locate the specific machine or server it's looking for, it is down to that machine to listen on any ports it chooses, and accept/deny/respond to any protocols on any ports configured.
For example, HTTP web services are usually provided on port 80. That means that once the client knows a machine IP, it can assume that sending a message to port 80 will result in that message being read/responded by that machine's web service. But it doesn't have to be that way. If the server is configured to listen for web incoming requests on port 9000, any client able to reach port 9000 will be able to reach its web service. If the server is behind a proxy/NAT/router that redirects port 10000 to port 9000, and the client sends a web request on port 10000, the server will receive it on port 9000 and respond as well.
Redirect/mapping within the web server
You asked about redirect mapping or rewrite in a comment. These are functions a web server can do. Basically, you can configure the web server (or most/many web servers) to manage how it handles the URL it receives in a request. So it can internally modify the URL on receipt to make different URLs be handled the same way, or fix common typos (mapping), or it can actually respond to tell the client itself to ask a second time, using some different, replacement, URL (redirect).
These have their uses, and could in principle handle your use-case, but they don't sound like the "right" solution for you, for these reasons:
- I don't think mapping would help at all. Mapping is almost totally internal to the web server, it says "treat this URL as if it's that URL". For example, you might use web server URL mapping to allow a user to query a forum using very-old, old and current URLs (for user convenience) using "https://example.com/index.php?area-=forum&topic=2", also "https://example.com/forum.php?topic=2" and also "https://forum.example.com?topic=2", and only handle this once, by mapping the first two of these onto the third URL internally, as the first step in handling the query. As this targets affects the query path not the IP/port, mapping isn't much use for port management, and in your case, the client never actually queries 8080 at all.
- Redirecting would work, but may not be what you want. Redirection in the web server relies upon the web server actually receiving the query (because these are web server internal functions). So the web server would have to listen on port 80 anyway to get the original query, inm order to respond with the redirect/map. It would also have to listen on port 8080. Functionally, it would need a redirect rule to have to tell any client querying port 80, to query it again using the ":8080" URL, which doesn't sound like what you want to do. The user would also see the new URL with ":8080" in it, whereas it sounds like you want it to be "transparent" and not shown.
- Also redirect would only work to redirect a standard port (80 or 443) - you couldn't redirect port 2000 to 8080 say, because the client wouldn't query on 2000 by default, in the first place, so it wouldn't ever get to the web server, even if it was listening on 2000. This might not be a problem for you though.
However if you want "intelligent" redirection, where only certain queries are rerouted to 8080, this might be the way to go, because redirect can include logic to decide which URLs should be redirected, whereas port mapping (below) would map everything.
How to correctly do it
The answer to your question is, you want the web server to respond to web requests which the client sends to the default port (80/443), but which the server actually receives on port 8080.
That means, as you can see, you need something in between that maps the ports between client and server. That way, the client sends on port 80 (default port used by web browsers), but it's actually received on port 8080 by the web server. Of course you will have to configure the web server to listen on port 8080, as this isn't standard, but it's easy and any web server should be able to have its listening ports specified.
The most usual way to do this would be within the router/firewall, via port mapping.
In simple terms, to do this, the router is given a rule, that anything received which has a destination IP of and destination port = 80, should be passed into the LAN with the destination port changed to 8080 instead. Neither the web server nor the client will be aware of the change (it's 100% handled by the router), so it will be 100% transparent to both of them. The client won't have ":8080" in its URL and won't need to redirect anything, since it queries port 80, and the web server can ignore port 80 and listen on 8080 only, since it never gets queries on port 80.
If you want a simple, straightforward way, similar to what a "DNS for ports" would do, this is probably the closest equivalent to what you're asking for in your question.
Solution 4:
You can't.
I mean, technically this could be done. DNS is famous for being able to submit a domain name and getting an IP address. However, I've studied the DNS protocol a bit, and really DNS is technically capable of acting as a query/response mechanism for far more than just domain names and IP addresses. One possible approach would be to use a DNS resource record that isn't the typical A or AAAA type, such as a TXT record (which is technically just text, and could be used for anything) or perhaps an SRV record, or any other newer resource record type you choose.
If you're making up your own software (both client and server), there may be no technical reason to not do such a thing, except do know that some people use DNS hosting companies and limit them to using only certain record types. That's unfortunate, as people who run their own DNS servers certainly have enough flexibility for such things.
However, if you aren't making up your own networking protocol (for example, if you want to use HTTP), you are likely to encounter a major problem, which is that existing software won't use your custom solution, unless you use solutions that are already established. That's going to be the barrier. Not a technical impossibility. A social barrier: Can you convince everybody to do things your way?
Now that I've explained why you can't do that, though, I may have a solution for what you're after. First, let's take a look at why we even have IP addresses and ports.
IP addresses and ports do different things. The purpose of the IP address is to fulfill the goals of Layers 2 and 3 of the OSI Model of network communications. The purpose of the IP address is to identify which computer the traffic is supposed to go to. The fact that we might use a port number for that purpose, by having firewalls/routers investigate port numbers in order to perform NAPT (Network Address Port-based Translation, also sometimes called PNAT or just NAT), is a newer technique which utilizes a resource (information), but was not part of the original design. If we step away from this "abuse" of the port numbers for a minute, and consider the original design, we may be able to find an easier solution. By the design of the Internet, machines were meant to be found using IP addresses.
The point of a "port number", used by TCP and UDP and some alternatives, is to be able to keep track of individual conversations. This helps to line up communication with running programs. So, if a machine receives traffic on TCP port 80, the machine will know that network traffic is meant to be used by the program that is the web server. If a web browser downloads multiple graphics simultaneously, combinations of "source port" numbers and "destination port" numbers can keep track of which data is meant for which graphic, so those simultaneous conversations can occur without mixing up the data.
Now, my guess is that you have access to a DNS server, and it seems to you like you think that DNS administration would be convenient to be able to handle some of the traffic routing a bit more. But DNS doesn't seem to be able to help you get a port number. What can you do?
Consider IPv6. IPv6 enables you to have way more IP addresses. Furthermore, unlike some implementations of IPv4, devices that use IPv6 can typically easily support multiple active IPv6 addresses at the same time. So, if you want to have three different network protocols on one computer, you could assign at least three different IPv6 addresses to the same computer. And then you can do whatever routing shenanigans you like with those IPv6 addresses.
Then, you can use the AAAA resource record type to assign a name to that IPv6 address, which your network design can treat as being effectively dedicated to the specific service on the specific computer you want.
Wallah, you now have DNS effectively pointing to the piece of software, and accomplished that goal without needing to try to rely on making DNS point to a port number, which doesn't work well simply because that functionality just so happens to not be commonly supported.
Possible objection:
And if you feel stuck with IPv4 and think that IPv6 is somehow not supported, I would encourage you to try to tackle that problem. That problem will probably be easier to fix (perhaps using some sort of tunneling), and will probably end up being a more rewarding fix once you have it implemented.