Thread: Starting a PostgreSQL server on a dynamic port (parameter port=0)
Starting a PostgreSQL server on a dynamic port (parameter port=0)
From
a.mitrokhin@postgrespro.ru
Date:
Hello. Postgres does not allow starting the server with port=0, which prevents it from obtaining an arbitrary free port from the kernel. ~$ LANG=C pg_ctl -D data -o "-c port=0" start 2025-07-10 05:27:02.785 GMT [702503] FATAL: 0 is outside the valid range for parameter "port" (1 .. 65535) This makes it unreliable to start the server in my tests without the risk of port conflicts with already running programs, unless resorting to an unreliable and race-condition-prone procedure of reserving ports in advance. Could you please fix this?
On Thu, 10 Jul 2025 at 12:15, <a.mitrokhin@postgrespro.ru> wrote: > > Hello. > > > Postgres does not allow starting the server with port=0, which prevents > it from obtaining an arbitrary free port from the kernel. > > > ~$ LANG=C pg_ctl -D data -o "-c port=0" start > 2025-07-10 05:27:02.785 GMT [702503] FATAL: 0 is outside the valid > range for parameter "port" (1 .. 65535) > > > This makes it unreliable to start the server in my tests without the > risk of port conflicts with already running programs, unless resorting > to an unreliable and race-condition-prone procedure of reserving ports > in advance. > > > Could you please fix this? Regression tests somehow solve this problem without any patch, so why this should be fixed? -- Best regards, Kirill Reshke
Re: Starting a PostgreSQL server on a dynamic port (parameter port=0)
From
a.mitrokhin@postgrespro.ru
Date:
Kirill Reshke писал(а) 2025-07-10 14:46: > On Thu, 10 Jul 2025 at 12:15, <a.mitrokhin@postgrespro.ru> wrote: >> >> Hello. >> >> >> Postgres does not allow starting the server with port=0, which >> prevents >> it from obtaining an arbitrary free port from the kernel. >> >> >> ~$ LANG=C pg_ctl -D data -o "-c port=0" start >> 2025-07-10 05:27:02.785 GMT [702503] FATAL: 0 is outside the valid >> range for parameter "port" (1 .. 65535) >> >> >> This makes it unreliable to start the server in my tests without the >> risk of port conflicts with already running programs, unless resorting >> to an unreliable and race-condition-prone procedure of reserving ports >> in advance. >> >> >> Could you please fix this? > > > Regression tests somehow solve this problem without any patch, so why > this should be fixed? This has nothing to do with Postgres regression tests. The issue is the practical benefit of using a dynamic port, which we're depriving ourselves of. If you're not interested in this behavior, you'll never use it. But there are cases where it can be very convenient. Why artificially restrict functionality that is simple, doesn't conflict with anything, and has no negative side effects?
On Thu, 2025-07-10 at 15:29 +0700, a.mitrokhin@postgrespro.ru wrote: > > > Postgres does not allow starting the server with port=0, which prevents > > > it from obtaining an arbitrary free port from the kernel. > > This has nothing to do with Postgres regression tests. The issue is > the practical benefit of using a dynamic port, which we're depriving > ourselves of. > > If you're not interested in this behavior, you'll never use it. But > there are cases where it can be very convenient. Why artificially > restrict functionality that is simple, doesn't conflict with anything, > and has no negative side effects? I have never wished for such a feature, and I can see negative side effects. If the server listens on a different port than you expect, it is easier to connect to the wrong server by mistake. Yours, Laurenz Albe
On 10.07.25 10:53, Laurenz Albe wrote: > I have never wished for such a feature, and I can see negative side > effects. If the server listens on a different port than you expect, > it is easier to connect to the wrong server by mistake. Moreover, there's a risk that postgres could potentially hijack the port of an application that's not currently running, but has a fixed port configuration assigned to it. This could, in turn, prevent the application from starting up successfully. I can understand why it might be attractive for some scenarios, but the risks and consequences could outweigh the benefits. Best, Jim
Re: Starting a PostgreSQL server on a dynamic port (parameter port=0)
From
"David G. Johnston"
Date:
On Thursday, July 10, 2025, <a.mitrokhin@postgrespro.ru> wrote:
If you're not interested in this behavior, you'll never use it. But
there are cases where it can be very convenient. Why artificially
restrict functionality that is simple, doesn't conflict with anything,
and has no negative side effects?
Then figure out how to do it on all the OSes we support and propose a patch. Maybe it’s simple enough to include. Maybe not. If it is simple e on an OS one cares about a shell script around pg_ctl is a simple way to leverage it so it’s still a fairly low priority to add into core.
David J.
On Thu, Jul 10, 2025, at 10:21 AM, David G. Johnston wrote: > On Thursday, July 10, 2025, <a.mitrokhin@postgrespro.ru> wrote: >> >> If you're not interested in this behavior, you'll never use it. But >> there are cases where it can be very convenient. Why artificially >> restrict functionality that is simple, doesn't conflict with anything, >> and has no negative side effects? > > Then figure out how to do it on all the OSes we support and propose a > patch. Maybe it’s simple enough to include. Maybe not. If it is > simple e on an OS one cares about a shell script around pg_ctl is a > simple way to leverage it so it’s still a fairly low priority to add > into core. > I don't think it is just a matter of operating system supports it. Linux and Windows supports port 0 but FreeBSD does not. The RFC 63335 [1] that is referred in the IANA document [2] says: Reserved: Reserved port numbers are not available for regular assignment; they are "assigned to IANA" for special purposes. Reserved port numbers include values at the edges of each range, e.g., 0, 1023, 1024, etc., which may be used to extend these ranges or the overall port number space in the future. Some operating systems like Linux and Windows decided to use it to automatically assign a free port. I don't think it is a good idea for production. The main reason is security, we had some reports[3][4] in the past. Some services like apache and nginx that don't allow you to use port 0. IMO it could be supported for development purposes. However, the test suite (pg_regress and TAP tests) already has some logic to assign a port from the private range (49152-65535) and is capable of assigning another port if the current port is in use. Maybe the OP has a case that the current approach is not ideal. [1] https://www.rfc-editor.org/rfc/rfc6335.html [2] https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml [3] https://medium.com/@ian.barwise/socket-programming-the-bizarre-tcp-ip-port-0-saga-b5c302d04299 [4] https://nvd.nist.gov/vuln/detail/cve-2023-27567#:~:text=Description,rule%20can%20crash%20the%20kernel. -- Euler Taveira EDB https://www.enterprisedb.com/
a.mitrokhin@postgrespro.ru writes: > Postgres does not allow starting the server with port=0, which prevents > it from obtaining an arbitrary free port from the kernel. Others have already pointed out problems with this proposal, but the one I see is: what do you do next? How will clients know what port to connect to? The only way I could see to do that is to read the port out of postmaster.pid, which works only for clients running as the same userid as the postmaster, which is surely an unfit-for-production approach. If you're only interested in this for testing purposes, we already have perfectly good free-port-selection algorithms embedded in our test harnesses. For that matter, in a test environment it's usually best (most secure) to use a Unix socket in a private directory, in which case there is little need to worry about port number conflicts in the first place. regards, tom lane
Re: Starting a PostgreSQL server on a dynamic port (parameter port=0)
From
a.mitrokhin@postgrespro.ru
Date:
Tom Lane писал(а) 2025-07-10 21:41: > a.mitrokhin@postgrespro.ru writes: >> Postgres does not allow starting the server with port=0, which >> prevents >> it from obtaining an arbitrary free port from the kernel. > > Others have already pointed out problems with this proposal, but > the one I see is: what do you do next? How will clients know > what port to connect to? > > The only way I could see to do that is to read the port out of > postmaster.pid, which works only for clients running as the same > userid as the postmaster, which is surely an unfit-for-production > approach. > > If you're only interested in this for testing purposes, we > already have perfectly good free-port-selection algorithms > embedded in our test harnesses. For that matter, in a test > environment it's usually best (most secure) to use a Unix > socket in a private directory, in which case there is little > need to worry about port number conflicts in the first place. > I looked at get_free_port(). Here's how it works: - It selects a port from the range 10200..32767, - Checks that the port is not in use, and - Verifies there’s no file created for that reserved port. There’s a race condition between bind() and the actual process launch, and it’s not handled (I don’t think there’s a simple solution with this approach). The port could be taken by any connection in the system or by another developer running their own tests on the same host (and they likely have their own directory with port reservation files). It would be much simpler to just start the server and use the port assigned by the OS kernel. The vast majority of test scenarios would work fine this way (I believe).