I am trying to learn how to use sockets to send files between pcs on my local network.
I am using ubuntu on my 'server' and my original plan was to create a ufw rule that allows all LAN connections but ask for a password when accepting the socket connection. That way only devices that are really supposed to communicate with the server would be accepted.
I do realise that creating ufw rules for static IPs would be an option but unfortunately I am dealing with dynamic IPs.
I have a text file of allowed keys on my 'server' and a text file containing one authentication key on the 'client'.
The server script looks like this:
#!/usr/bin/env python3
import socket
with open('/path/to/allowedKeys') as f:
allowedKeys = []
for line in f:
allowedKeys.append(line.rstrip('\n'))
HOST = '127.0.0.1' #standard loopback interface address (localhost)
PORT = 9999
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind((HOST, PORT))
serversocket.listen()
(clientsocket, address) = serversocket.accept()
with clientsocket:
print('Connected by', address)
while True:
data = clientsocket.recv(1024)
data = data.decode(encoding="utf-8")
print('Received', repr(data))
if data in allowedKeys:
clientsocket.sendall(b'Thank you for logging in.')
clientsocket.shutdown(socket.SHUT_RDWR)
break
else:
clientsocket.sendall(b'Error: Failed authentication')
clientsocket.shutdown(socket.SHUT_RDWR)
break
and the client script looks like this:
#!/usr/bin/env python3
import socket
with open('/path/to/authenticationKey', 'r') as f: #read authenticationKey from textfile
authenticationKey = f.readline().rstrip('\n')
authenticationKey = bytes(authenticationKey, encoding="utf-8") #convert authenticationKey to bytes
#authenticationKey = bytes('wrongKey', encoding="utf-8") #wrong Key for testing
HOST = '127.0.0.1' #server hostname or IP address
PORT = 9999 #port used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(authenticationKey)
data = s.recv(1024)
s.shutdown(socket.SHUT_RDWR)
s.close()
print('Received', repr(data))
When I execute the scripts it looks like everything works as expected. I get either
Received 'nhjp9NIin987BUHBlkuULK98zJKn98JH'
or
Received 'wrongKey'
and the server shuts down successfully.
I have looked at these two related questions:
socket accept only specific addresses?
Server socket - accept connections only from IP addresses in the whitelist
While I cannot filter by IP it seems as if one must first accept the connection in order to authenticate the client.
I only want devices that possess an allowed key to be able to communicate with the server. All other connections should be shut down.
Since I still have very limited knowledge I would like to know whether this is the way to go or whether this leaves me open to any vulnerabilities.