python bind socket.error: [Errno 13] Permission denied
Question:
I have a python script which gets packets from a remote machine and writes them
(os.write(self.tun_fd.fileno(), ”.join(packet))) to a tun interface gr3:
Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.0.0.6 P-t-P:10.0.0.8 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:61 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:5124 (5.0 KiB) TX bytes:0 (0.0 b)
I would like to receive those packets via a separate pong script as follows:
import threading, os, sys, fcntl, struct, socket
from fcntl import ioctl
from packet import Packet
HOST = '10.0.0.6'
PORT = 111
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(1024)
if not data: break
else: print data
conn.sendall(data)
conn.close()
I got this error :
s.bind((HOST, PORT))
File "<string>", line 1, in bind
socket.error: [Errno 13] Permission denied
Answers:
You can’t bind to port numbers lower than 1024 as a unprivileged user.
So you should either:
- Use a port number larger than 1024 (recommended)
- Or run the script as a privileged user
Harder, but more secure solution if it’s really necessary to accept from 111:
- Run the as unprivileged on a higher port, and forward port 111 to it externally.
Although not in the original question, just want to expand this to the case of unix sockets for local interprocess communication, i.e. AF_UNIX
. As seen in man unix 7
:
In the Linux implementation, pathname sockets honor the permissions of
the directory they are in. Creation of a new socket fails if the
process does not have write and search (execute) permission on the
directory in which the socket is created.
On Linux, connecting to a stream socket object requires write
permission on that socket; sending a datagram to a datagram socket
likewise requires write permission on that socket. POSIX does not make
any statement about the effect of the permissions on a socket file,
and on some systems (e.g., older BSDs), the socket permissions are
ignored. Portable programs should not rely on this feature for
security.
So look at the permissions on the socket directory if getting a PermissionError: [Errno 13] Permission denied
on bind()
for unix sockets.
For anyone else that came to this page for the same error:
Your server may not be running with root privileges. All ports under 1024 are system reserved. You’ll need help from a server with root privileges.
For my specific scenario what worked was to setup a reverse proxy with Nginx to my application on a higher numbered port.
In my case the production server I had deployed: Waitress didn’t run as root and so didn’t support opening ports on the system reserved ports. Launching Nginx to handle SSL encryption and passing all https requests to the application port via http was what worked for me.
I would first make sure that nothing else is using the port you are trying to use and if its clear then make sure your deployed server is setup to handle that port.
This was the documentation I found that explained the situation clearly to me after a lot of hair pulling:
Binding Externally
Waitress should not be run as root because it would cause your
application code to run as root, which is not secure. However, this
means it will not be possible to bind to port 80 or 443. Instead, a
reverse proxy such as nginx or Apache httpd should be used in front of
Waitress.
You can bind to all external IPs on a non-privileged port by not
specifying the –host option. Don’t do this when using a revers proxy
setup, otherwise it will be possible to bypass the proxy.
0.0.0.0 is not a valid address to navigate to, you’d use a specific IP address in your browser.
src= https://flask.palletsprojects.com/en/2.2.x/deploying/waitress/
I have a python script which gets packets from a remote machine and writes them
(os.write(self.tun_fd.fileno(), ”.join(packet))) to a tun interface gr3:
Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.0.0.6 P-t-P:10.0.0.8 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:61 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:5124 (5.0 KiB) TX bytes:0 (0.0 b)
I would like to receive those packets via a separate pong script as follows:
import threading, os, sys, fcntl, struct, socket
from fcntl import ioctl
from packet import Packet
HOST = '10.0.0.6'
PORT = 111
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(1024)
if not data: break
else: print data
conn.sendall(data)
conn.close()
I got this error :
s.bind((HOST, PORT))
File "<string>", line 1, in bind
socket.error: [Errno 13] Permission denied
You can’t bind to port numbers lower than 1024 as a unprivileged user.
So you should either:
- Use a port number larger than 1024 (recommended)
- Or run the script as a privileged user
Harder, but more secure solution if it’s really necessary to accept from 111:
- Run the as unprivileged on a higher port, and forward port 111 to it externally.
Although not in the original question, just want to expand this to the case of unix sockets for local interprocess communication, i.e. AF_UNIX
. As seen in man unix 7
:
In the Linux implementation, pathname sockets honor the permissions of
the directory they are in. Creation of a new socket fails if the
process does not have write and search (execute) permission on the
directory in which the socket is created.On Linux, connecting to a stream socket object requires write
permission on that socket; sending a datagram to a datagram socket
likewise requires write permission on that socket. POSIX does not make
any statement about the effect of the permissions on a socket file,
and on some systems (e.g., older BSDs), the socket permissions are
ignored. Portable programs should not rely on this feature for
security.
So look at the permissions on the socket directory if getting a PermissionError: [Errno 13] Permission denied
on bind()
for unix sockets.
For anyone else that came to this page for the same error:
Your server may not be running with root privileges. All ports under 1024 are system reserved. You’ll need help from a server with root privileges.
For my specific scenario what worked was to setup a reverse proxy with Nginx to my application on a higher numbered port.
In my case the production server I had deployed: Waitress didn’t run as root and so didn’t support opening ports on the system reserved ports. Launching Nginx to handle SSL encryption and passing all https requests to the application port via http was what worked for me.
I would first make sure that nothing else is using the port you are trying to use and if its clear then make sure your deployed server is setup to handle that port.
This was the documentation I found that explained the situation clearly to me after a lot of hair pulling:
Binding Externally
Waitress should not be run as root because it would cause your
application code to run as root, which is not secure. However, this
means it will not be possible to bind to port 80 or 443. Instead, a
reverse proxy such as nginx or Apache httpd should be used in front of
Waitress.You can bind to all external IPs on a non-privileged port by not
specifying the –host option. Don’t do this when using a revers proxy
setup, otherwise it will be possible to bypass the proxy.0.0.0.0 is not a valid address to navigate to, you’d use a specific IP address in your browser.
src= https://flask.palletsprojects.com/en/2.2.x/deploying/waitress/