Python:仅接受具有身份验证的套接字

Python:仅接受具有身份验证的套接字,python,sockets,Python,Sockets,我正在尝试学习如何使用套接字在本地网络上的PC之间发送文件 我在我的“服务器”上使用ubuntu,我最初的计划是创建一个ufw规则,允许所有LAN连接,但在接受套接字连接时要求输入密码。这样,只有真正应该与服务器通信的设备才会被接受 我意识到为静态IP创建ufw规则将是一种选择,但不幸的是,我正在处理动态IP 我在“服务器”上有一个包含允许密钥的文本文件,在“客户端”上有一个包含一个身份验证密钥的文本文件 服务器脚本如下所示: #!/usr/bin/env python3 import soc

我正在尝试学习如何使用套接字在本地网络上的PC之间发送文件

我在我的“服务器”上使用ubuntu,我最初的计划是创建一个ufw规则,允许所有LAN连接,但在接受套接字连接时要求输入密码。这样,只有真正应该与服务器通信的设备才会被接受

我意识到为静态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))
客户端脚本如下所示:

#!/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'

并且服务器成功关闭

我已经研究了这两个相关问题:

虽然我不能通过IP进行过滤,但似乎必须首先接受连接才能对客户端进行身份验证

我只希望拥有允许密钥的设备能够与服务器通信。应关闭所有其他连接

由于我的知识仍然非常有限,我想知道这是否是一条路要走,或者这是否会让我面临任何漏洞

虽然我不能通过IP进行过滤,但似乎必须首先接受连接才能对客户端进行身份验证。我只想要拥有允许密钥的设备

由于您希望根据实际数据(密钥或密钥拥有证明)对客户机进行身份验证,因此必须首先建立能够从客户机传输数据的连接。对于TCP,这意味着您必须接受连接

。。。这是否会让我暴露任何弱点

这是通常的做法,但它会让您面临拒绝服务攻击。创建新连接需要资源,因此通过打开大量连接,攻击者可以耗尽服务器资源。如果以这种方式耗尽所有资源,则即使有效用户也无法再访问服务器。例如,参见攻击


根据客户端的设置,可以添加其他保护。但这些都超出了python应用程序的范围,并且大部分都超出了这个问题的范围。但是要想了解一些想法,请参阅Wikipedia文章中有关对策的部分。

如果我的python脚本没有运行并检查传入的连接,该怎么办。现在有人可以从我的本地网络连接到我的服务器了吗?@Sean:你的Python脚本和监听插座基本上是一扇打开的门,有人可以进入。没有打开的门,没有进入-至少没有通过这扇门。当然,房子可能有其他的门(即其他服务,如web服务器、邮件服务器等)。现在我有点困惑。一旦我设置了一个ufw规则,允许所有来自本地网络的连接,这难道不会打开大门吗?或者这只是允许入站连接,但必须有一个主动接受所述连接的服务?由于我的知识非常有限,我不想在事故中造成任何恶作剧。@Sean:ufw这样的防火墙类似于门卫,可以允许或拒绝访问门本身,但不能打开一扇关闭的门。