我正在学习如何使用套接字在本地网络上的PC之间发送文件。
我在我的服务器上使用ubuntu,我最初的计划是创建一个ufw规则,允许所有的局域网连接,但在接受套接字连接时要求密码。这样只有真正应该与服务器通信的设备才会被接受。
我确实意识到为静态IP创建ufw规则是一种选择,但不幸的是,我正在处理动态IP。
我在“服务器”上有一个允许密钥的文本文件,在“客户端”上有一个包含身份验证密钥的文本文件。
服务器脚本如下所示:
#!/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
字符串
客户端脚本看起来像这样:
#!/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))
型
当我执行脚本时,看起来一切都像预期的那样工作。
Received 'nhjp9NIin987BUHBlkuULK98zJKn98JH'
型
或
Received 'wrongKey'
型
服务器成功关闭。
我看了这两个相关的问题:
socket accept only specific addresses?
Server socket - accept connections only from IP addresses in the whitelist的
虽然我不能通过IP过滤,但似乎必须首先接受连接才能验证客户端。
我只希望拥有允许的密钥的设备能够与服务器通信。所有其他连接都应关闭。
由于我的知识仍然非常有限,我想知道这是否是要走的路,或者这是否会让我面临任何漏洞。
2条答案
按热度按时间muk1a3rh1#
虽然我不能通过IP过滤,但似乎必须首先接受连接才能对客户端进行身份验证。我只想要拥有允许密钥的设备。
由于您希望根据实际数据(密钥或持有密钥的证明)对客户端进行身份验证,因此您必须首先拥有一个能够从客户端传输数据的连接。使用TCP,这意味着您必须接受连接。
……这是否会让我暴露出任何弱点。
这是一种常见的方法,但它会让您容易受到拒绝服务攻击。创建一个新的连接会占用资源,因此通过打开大量连接,攻击者可以耗尽服务器资源。如果所有资源都耗尽,即使是合法用户也无法再访问服务器。例如,请参阅SYN flood攻击。
根据客户端的设置,可以添加额外的保护。但是这些都在python应用程序之外,并且大多超出了这个问题的范围。但是要获得一些想法,请参阅Wikipedia文章中关于对策的部分。
2lpgd9682#
您可以使用代理。基本上在代理中进行身份验证并发送请求,然后将请求转发到主应用程序。